Python
What Happens to Python Objects When You Stop Using Them? A Deep Dive into Garbage Collection
Explore Python's dual memory management system: reference counting handles objects immediately, while generational garbage collection catches circular references efficiently to prevent memory leaks.
June 2026 · 7 min read · 1 views · 0 hearts
Advertisement
What Happens to Python Objects When You Stop Using Them? A Deep Dive into Garbage Collection
You've probably heard that Python handles memory management automatically. But have you ever wondered what's actually happening behind the scenes when you delete a variable or a function finishes? Python's garbage collection isn't magic—it's a carefully designed system that keeps your programs from eating all your RAM.
Let's peek under the hood.
The Two Pillars of Python Memory Management
Python uses a dual approach to clean up unused objects:
- Reference counting — immediate, simple, but has a blind spot
- Generational garbage collection — catches what reference counting misses
Both work together, and understanding them can save you from memory leaks you didn't know you were creating.
Reference Counting: The First Line of Defense
Every Python object has a refcount — a counter tracking how many references point to it. When you write:
x = [1, 2, 3] # refcount = 1
y = x # refcount = 2
del x # refcount = 1
y = None # refcount = 0 → gets deleted immediately
The moment that counter hits zero, Python reclaims the memory right then. This is why Python programs don't usually need explicit free() calls — they clean up aggressively.
The catch? Reference counting can't handle circular references.
The Reference Counting Blind Spot
Consider this:
class Node:
def __init__(self):
self.neighbor = None
a = Node()
b = Node()
a.neighbor = b # b's refcount = 2 (a + local variable)
b.neighbor = a # a's refcount = 2 (b + local variable)
del a # a's refcount = 1 (still referenced by b.neighbor)
del b # b's refcount = 1 (still referenced by a.neighbor)
Now both a and b are unreachable from your code, but their refcounts are stuck at 1. They'll sit in memory forever unless something else kicks in.
That's where the garbage collector enters.
Generational Garbage Collection: The Cleanup Crew
Python's gc module runs a cycle-detector that finds and collects circular garbage. But it doesn't scan every object every time — that would be absurdly slow.
Instead, it uses three generations:
| Generation | Purpose | Collection Frequency |
|---|---|---|
| 0 | Young objects (short-lived) | Very often |
| 1 | Survivors from gen 0 | Less often |
| 2 | Long-lived objects | Rarely |
New objects start in generation 0. If they survive a collection cycle, they get promoted. Most objects die young (temporary variables, intermediate results), so generation 0 gets cleaned frequently. The oldest generation might only get scanned every few hundred collections.
This design is why Python can handle millions of short-lived objects without grinding to a halt.
How to See the GC in Action
You don't need to take my word for it. Python exposes the garbage collector through the gc module:
import gc
# See current thresholds
print(gc.get_threshold()) # (700, 10, 10) by default
# Manually trigger collection
collected = gc.collect()
print(f"Collected {collected} objects")
The tuple (700, 10, 10) means:
- Collect generation 0 when it has 700 objects
- Collect generation 1 after 10 generation-0 collections
- Collect generation 2 after 10 generation-1 collections
When Does the GC Actually Run?
Not every time you delete a variable. The garbage collector triggers automatically when:
- The number of allocations minus deallocations in generation 0 hits the threshold
- You call
gc.collect()manually - Certain C extensions request it
This means if your program creates and destroys objects quickly (like in a tight loop), the GC might not interfere at all — reference counting handles it.
Common Pitfalls That Break Garbage Collection
1. __del__ methods
If a class defines __del__, objects with circular references that also have this method can't be collected automatically. Python doesn't know what order to call them in.
class Leaky:
def __del__(self):
print("Cleanup!")
If two Leaky objects reference each other, they become uncollectible. Solution? Avoid __del__ in cyclic structures, or break the cycle manually.
2. Keeping references in globals or caches
A list you store in a global variable or a dictionary you use as a cache holds references forever. If that list grows over time, the GC won't save you — those objects are still reachable.
cache = {}
def fetch_data(key):
if key not in cache:
cache[key] = expensive_operation()
return cache[key]
This is fine until your cache grows unbounded. Consider using functools.lru_cache with a size limit.
3. C extensions and non-Python memory
The GC only tracks Python objects. If a C extension allocates memory that Python objects reference, and that allocation doesn't update Python's memory views, you can leak memory that the GC has no idea about.
Tuning the Garbage Collector
For most programs, the defaults work fine. But if you're doing something unusual — like running a real-time system or handling enormous data — you can adjust:
import gc
# Turn off automatic collection (risky, but avoids pauses)
gc.disable()
# Only collect manually at predictable points
gc.collect()
# Or adjust thresholds
gc.set_threshold(500, 5, 5) # More frequent collections
Warning: Disabling the GC without understanding circular references will leak memory. Only do this if you're certain your code avoids cycles.
The Bottom Line
Python's garbage collection isn't mysterious. Reference counting handles the common case instantly. The generational collector catches cycles efficiently by focusing on young objects. Together, they let you write code without micromanaging memory — as long as you avoid a few sharp edges.
Next time you see a memory leak, check for circular references, lingering __del__ methods, or growing caches. Almost always, the problem is reachable objects you forgot to release — not the garbage collector failing to do its job.
Advertisement
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.