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).