Memory Management: Reference Counting, Cyclic GC & Context Managers (with)
1Concept
CPython uses Reference Counting (ob_refcnt) as primary GC: objects are deallocated the instant refcount drops to 0. A 3-generation cyclic garbage collector resolves circular reference graphs. Context managers (with open() as f:) guarantee cleanup via __enter__ and __exit__.
2Architecture Diagram
PyObject Structure: +-------------------------------------+ | ob_refcnt : Number of active ptrs | ──► When refcnt == 0: Memory immediately freed! | ob_type : Pointer to type object | | Data payload | +-------------------------------------+
3Code Example
Stage 0 Language Foundations
import sys
class CustomResource:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f"[Context Manager] Acquired {self.name}")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"[Context Manager] Released {self.name}")
return False # Propagate exceptions if any
with CustomResource("Database Connection") as res:
print(f"Working with {res.name}...")4Expected Output
[Context Manager] Acquired Database Connection Working with Database Connection... [Context Manager] Released Database Connection
5Key Takeaways
- ✓Use context managers (with statement) to guarantee file/socket closure.
- ✓Reference counting provides deterministic deallocation except for reference cycles.
- ✓Use weakref to break cyclic references in object graphs.