Python · The language, not just syntax
How does Python's garbage collector handle cycles?
Short answer
Reference counting cannot free reference cycles, so CPython runs a generational cyclic collector that detects unreachable groups of objects. The gc module exposes thresholds, stats and manual collection.
Most objects die when their reference count hits zero. A cycle, such as a parent referencing a child that references the parent, keeps counts above zero even when nothing external points to the group. The cyclic collector finds those unreachable groups and frees them.
import gc
import weakref
class Node:
def __init__(self, name):
self.name = name
self.peer = None
first = Node("first")
second = Node("second")
first.peer = second
second.peer = first
ref = weakref.ref(first)
del first
print(ref() is not None)
gc.collect()
print(ref() is None)Generations and tuning
- Objects move through three generations as they survive collections
- Younger generations are collected more often because most objects die young
- gc.get_threshold and gc.set_threshold control when collections trigger
- gc.disable is only reasonable for short-lived batch processes with measured impact
Disabling collection can reduce latency jitter in a batch job that exits soon, but in a long-running service it can grow memory without bound. If you tune it, measure pause times and memory, and remember that some libraries rely on finalisers running promptly.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why does reference counting alone fail on cycles?
- 2What are the three generations used for?
- 3When is disabling the GC defensible?
- 4What is a weak reference used for?
Say it in the interview
Reference counting frees most objects immediately, but it cannot free cycles, so CPython adds a generational cyclic collector. The collector focuses on young objects because most die early. I rarely tune the thresholds, and I only disable collection for measured short-lived batch work. For caches and observer registries I use weak references so entries do not keep objects alive.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Python mock interview and get scored feedback on depth, clarity and confidence.