Skip to main content

Memory model

Python's memory model is reference counting augmented by a generational cycle collector. Implementations must preserve the observable behaviour: prompt finalisation when refcount drops to zero, deferred cycle collection, weakref clearing before finalisation, and stable object identity.

Source-of-record: Objects/object.c, Modules/gcmodule.c, Objects/weakrefobject.c, the gc module docs.

Reference counting​

Every object carries ob_refcnt, an integer count of strong references. Mutating operations follow strict rules:

OperationRefcount change
Py_INCREF(obj)+1
Py_DECREF(obj)-1; if hits 0, call tp_dealloc.
Py_XINCREF(obj)+1 if obj != NULL.
Py_XDECREF(obj)-1 if obj != NULL.
Py_NewRef(obj)+1; returns obj.
Py_Clear(obj_ref)DECREF and set to NULL atomically.

Reference semantics​

TermMeaning
Strong referenceCounted; caller is responsible for releasing.
Borrowed referenceNot counted; caller must not outlive the source.
Stolen referenceFunction takes ownership; caller no longer DECREFs.
Returned referenceThe reference returned by a function is strong unless documented otherwise.

Singletons​

None, True, False, Ellipsis, NotImplemented, and small ints in [-5, 256] are immortal singletons. Their refcounts are incremented but never observed to reach zero. In 3.12+ they are immortal: their refcount is pinned at a sentinel value (_Py_IMMORTAL_REFCNT) and INCREF/DECREF are no-ops.

Cycle collector​

The cycle collector runs over objects whose type sets Py_TPFLAGS_HAVE_GC. It uses three generations.

GenerationThreshold (default)Promoted to
0700 allocationsGeneration 1.
110 collections of gen 0Generation 2.
210 collections of gen 1Stays.

Algorithm sketch​

Phase
Mark every GC-tracked object with its current refcount as gc_refs.
Visit each object's references; decrement gc_refs on internal references.
Objects with gc_refs > 0 have external references; mark them reachable.
Reachable set spreads via reference visit.
Anything unreachable is collectable.
Run finalisers; weakrefs cleared first.
Re-scan: if a resurrected object becomes reachable, keep it.
Free the rest.

gc module​

FunctionEffect
gc.collect(generation=2)Force collection up to generation.
gc.disable() / gc.enable()Pause/resume the automatic collector.
gc.isenabled()Predicate.
gc.set_threshold(t0, t1, t2)Configure thresholds.
gc.get_threshold()Current thresholds.
gc.get_count()Generation counters.
gc.get_objects(generation=None)All tracked objects.
gc.get_referents(*objs)What objs reference.
gc.get_referrers(*objs)What references objs.
gc.set_debug(flags)Debug flags: DEBUG_STATS, DEBUG_COLLECTABLE, etc.
gc.callbacksList of (phase, info) callbacks per cycle.
gc.freeze() / gc.unfreeze()Move tracked objects into a permanent gen 3.

Finalisation​

__del__​

Runs once when an object's refcount hits zero (or as part of cycle collection for unreachable cycles).

Rule
Inside __del__, exceptions are caught and logged to stderr, not propagated.
__del__ runs in the thread that drops the last refcount.
For cyclic garbage, __del__ runs in undefined order; cycles with multiple __del__ definitions are collectable but the runtime warns.
Resurrection (binding the object somewhere) is supported once; subsequent finalisations do not re-trigger __del__.

Order of operations​

Step
Cycle collector identifies unreachable set.
Weak references whose referent is unreachable are cleared and their callbacks queued.
tp_finalize (__del__) runs on each unreachable object.
Weakref callbacks run.
If any object was resurrected, re-scan; otherwise free the rest.

Weak references​

Type / functionPurpose
weakref.ref(obj[, callback])Weak reference object; call to retrieve obj.
weakref.proxy(obj[, callback])Transparent proxy.
weakref.WeakSetSet of weakrefs.
weakref.WeakValueDictionaryDict with weak values.
weakref.WeakKeyDictionaryDict with weak keys.
weakref.finalize(obj, fn, *a, **kw)Run fn(*a, **kw) when obj is collected.
weakref.getweakrefs(obj)All live weakrefs to obj.
weakref.getweakrefcount(obj)Number of live weakrefs to obj.

Weakref support requires the type to set Py_TPFLAGS_HAVE_GC (or to have a tp_weaklistoffset).

Memory layout​

Object header​

FieldTypeDescription
ob_refcntPy_ssize_tReference count.
ob_typePyTypeObject*Type pointer.
ob_sizePy_ssize_t(Variable-length objects only) length.

Type object​

A PyTypeObject is a PyObject extended with the slots described in Special methods.

GC header​

GC-tracked objects have an extra PyGC_Head immediately before the PyObject header:

FieldMeaning
_gc_nextLinked-list pointer.
_gc_prevLinked-list pointer; low bit holds GC flags.

Allocation​

AllocatorUsed for
PyMem_Malloc familyRaw memory.
PyObject_Malloc familyObject memory (pymalloc arenas).
_PyObject_GC_NewGC-tracked object.
Type-specific free listsSmall frequently-allocated types (frames, list iterators, tuples up to size 20, ints up to a cap).

pymalloc arenas​

TermSizeNotes
Arena1 MBAllocated via mmap.
Pool4 KBWithin an arena.
Block8 to 512 bytesWithin a pool; size class fixed per pool.

Anything larger than 512 bytes goes to the system allocator.

Identity guarantees​

Rule
id(x) is constant for the object's lifetime.
Two objects with disjoint lifetimes may share an id.
id(x) == id(y) implies x is y while both objects are alive.

Concurrency​

Rule
The GIL protects refcount updates; without it, every INCREF/DECREF would need atomics.
The cycle collector runs only with the GIL held.
PEP 703 (no-GIL) introduces deferred refcounting and biased reference counting; not yet the default.

Threading and __del__​

Rule
__del__ can run in any thread.
__del__ may resurrect the object once; subsequent finalisations skip __del__.
Py_TPFLAGS_HAVE_GC is required for __del__ to be honoured by the cycle collector.

Gopy status​

AreaState
Reference counting on every objectComplete.
Three-generation cycle collectorComplete.
Weak references and finalisersComplete.
__del__ ordering and resurrectionComplete.
gc module surfaceComplete.
Immortal singletonsComplete.
Free listsUsed selectively where they fit Go's allocator.
pymalloc arenasN/A; Go's runtime allocator handles object memory.

Reference​

  • Objects/object.c. Refcount API.
  • Modules/gcmodule.c. Cycle collector.
  • Objects/weakrefobject.c. Weakrefs.
  • objects/. gopy's port.
  • Internals -> GC.
  • PEP 442 (safe object finalisation).
  • PEP 703 (no-GIL).