Definition
CPython frees memory mainly by reference counting: each object tracks how many names refer to it, and is deleted when the count reaches zero. A separate garbage collector handles reference cycles. __slots__ and weakref help reduce memory use and keep-alive references.
In simple words
An object lives as long as somebody holds it. When the last person lets go, it's cleared away. If two objects only hold each other, the garbage collector notices and clears both.
Why it matters
Data work can run out of memory quickly. Knowing why memory is still in use, such as a forgotten reference to a huge DataFrame, is what fixes it.
How it works
In code
import gc
import sys
data = [1, 2, 3]
alias = data
print("References:", sys.getrefcount(data) - 1)
del alias
print("After del:", sys.getrefcount(data) - 1)
class Plain:
def __init__(self):
self.x = 1
class Slim:
__slots__ = ("x",)
def __init__(self):
self.x = 1
print("Plain has a dict:", hasattr(Plain(), "__dict__"))
print("Slim has a dict:", hasattr(Slim(), "__dict__"))
class Node:
pass
a, b = Node(), Node()
a.other, b.other = b, a # a cycle
del a, b
print("Cycle collected:", gc.collect() > 0)Output
References: 2 After del: 1 Plain has a dict: True Slim has a dict: False Cycle collected: True
Common mistakes
- Thinking del erases an object. It removes one name, and the object lives until no names are left.
- Keeping every intermediate result in a notebook, until memory runs out.
Check yourself
Summary
- Objects live until nothing refers to them.
- The garbage collector clears cycles.
- __slots__ reduces memory per object.
Finished reading?
Sources: Python docs: gc