Understanding Python Memory Management: Reference Counting, Circular References, and Generational Garbage Collection
Python abstracts memory management through reference counting, handles cyclic references with a generational garbage collector, and employs the weak generational hypothesis to efficiently reclaim objects, as illustrated by code examples demonstrating object creation, deletion, and the behavior of different GC generations.
If you have ever written C or C++, you know that memory management is critical and a small mistake can cause leaks.
When writing Python, however, we rarely think about memory handling—why is it so effortless?
Behind that convenience, Python silently manages memory for you; the following explains how.
1. Reference Counting
Python uses reference counting to manage memory.
When an object is created, a variable points to it, giving it a reference count of 1. Each additional variable that points to the object increments the count; removing a variable decrements it.
If an object’s reference count drops to 0, Python reclaims it.
Example code:
<code>class Person(object):
def __init__(self, name):
self.name = name
def __del__(self):
print('%s执行了del函数' % self.name)
while True:
p1 = Person('p1')
p2 = Person('p2')
del p1
del p2
a = input('test:')
</code>Running this shows that the `del` method of both objects is executed.
2. Circular References
Reference counting cannot resolve circular references.
For example, if object a references b and b references a, their counts never reach zero, so they are never reclaimed.
See the following example:
<code>class Person(object):
def __init__(self, name):
self.name = name
def __del__(self):
print('%s执行了del函数' % self.name)
while True:
p1 = Person('p1')
p2 = Person('p2')
# 循环引用后,永远得不到释放
p1.next = p2
p2.prev = p1
del p1
del p2
a = input('test:')
</code>In this case the `del` functions are not called because the circular reference prevents the objects from being released.
3. Mark‑Sweep and Generational Collection
When a new object is created, Python places it on an internal “zero‑generation” list.
Consider creating four `Person` objects (p1‑p4) where p1 and p2 reference each other, and p3 and p4 have a reference count of 2:
<code>import sys
class Person(object):
def __init__(self, name):
self.name = name
self.next = None
self.prev = None
p1 = Person('p1')
p2 = Person('p2')
p3 = Person('p3')
p4 = Person('p4')
p1.next = p2
p2.prev = p1
temp1 = p3
temp2 = p4
print(sys.getrefcount(p1))
print(sys.getrefcount(p2))
print(sys.getrefcount(p3))
print(sys.getrefcount(p4))
</code>The above code puts p1, p2, p3, and p4 onto the zero‑generation list (see diagram).
Because p1 and p2 reference each other, they form a circular reference; even after `del p1` and `del p2`, they remain unreleased.
Python therefore activates a new garbage‑collection mechanism. When the total number of allocated objects minus the number of reclaimed objects exceeds a threshold, the collector scans the zero‑generation list, reduces reference counts of objects involved in cycles, and frees those whose count drops to zero (e.g., p1 and p2).
Unreleased objects are then moved to a “first‑generation” list.
After the zero‑generation list has been processed a certain number of times, the collector traverses the first‑generation list and promotes surviving objects to a “second‑generation” list, applying the same principle.
4. Weak Generational Hypothesis
The core idea of generational GC is that the collector should handle new objects more frequently. An object that has just been created is “young”; an object that survives several collection cycles is “old”.
The hypothesis states that most young objects die quickly, while older objects tend to live longer.
Thus, most newly created objects become garbage soon after use, whereas occasional objects (e.g., web‑session data or configuration) persist for a long time.
By focusing on the zero‑generation list, Python’s collector spends most of its time reclaiming short‑lived objects and only occasionally processes older generations when thresholds are met.
- END -
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.