Memory Modelhigh

Cyclic Garbage Collector

Python's gc module handles objects with circular references that reference counting alone cannot free.

Memory anchor

Cyclic GC = the janitor who untangles Christmas lights. Ref counting handles lone bulbs fine, but when two strands are tangled in a loop, only the janitor can cut through and reclaim them.

Expected depth

The GC runs periodically in three generations (0, 1, 2). Objects survive to older generations the longer they live — most objects die young (generational hypothesis). You can trigger manually with gc.collect(). gc.disable() turns off the cyclic GC (safe if you avoid circular references). Objects tracked by the GC have a small overhead.

Deep — senior internals

The GC uses a 'mark and sweep'-like algorithm — it finds all container objects that are reachable only from other cyclic garbage. The three generations have thresholds (default 700/10/10): when generation 0 exceeds its threshold, a collection runs and survivors are promoted. The GC overhead is why some high-performance Python code explicitly avoids circular references and disables gc.collect(). Python 3.12 improves GC performance significantly. __del__ complicates GC — objects with finalizers were historically uncollectable in cycles (fixed in Python 3.4+).

🎤Interview-ready answer

Reference counting can't free circular references. Python's cyclic GC periodically scans container objects for cycles and frees them. It uses three generations for efficiency — most objects die young so only gen-0 runs frequently. You can tune thresholds with gc.set_threshold() or disable it entirely with gc.disable() in performance-critical code where you control your object graph.

Common trap

gc.disable() doesn't disable reference counting — that always runs. It only disables the cyclic collector. If you have no cycles, gc.disable() has no downside and can speed up allocation-heavy code.