When Python frees an object, and when it waits for the collector

del frees an object the moment its last reference goes. Two objects that point at each other stay in memory until the cycle collector runs.

Read the explanation

Predict first

After del b, c, nothing in main can reach b or c. When are they freed?

0123456789main: a = Buffer("a")a =main: del a: free adel aprintmain: make b, c, link themb, cmain: del b, c: nothing freeddelprintgc.collect(): free b, cprintalive: 1 referenceobjects b and c: alive: main + each otheraliveunreachable, still in memory

Tap any block to see what that thread is doing.

  • Running
  • Waiting / parked
Step 1/5

Every CPython object counts its references. a has one: the name a.

1class Buffer:2    def __init__(self, name):3        self.name = name4        self.other = None5        weakref.finalize(self, print, f"free {name}")  # prints when the object is freed6 7def main():8    a = Buffer("a")9    del a  # the last reference is gone: freed right now10    print("after del a")11 12    b, c = Buffer("b"), Buffer("c")13    b.other, c.other = c, b  # a cycle: each keeps the other alive14    del b, c  # unreachable now, but each still has a reference15    print("after del b, c")16    gc.collect()  # the cycle collector finds them and frees both17    print("after gc.collect()")18 19if __name__ == "__main__":20    main()

Explanation

What just happened

CPython counts the references to every object. del a removed the last one, so a was freed right inside del, before the next line ran.

b and c pointed at each other. After del b, c, no code could reach them, but each still held the other, so neither count reached 0. They stayed in memory until gc.collect() ran the cycle collector, which spotted the unreachable pair and freed both.

Why there are two mechanisms

Reference counting is immediate and cheap, but it can’t see cycles. The cycle collector can, so it runs from time to time to catch them. Most objects never need it.

Watch out

gc.disable() turns off only the cycle collector. Cycles then live until the process ends, however much you allocate; everything else is still freed by reference counting.

Common questions

Does del free memory in Python?

Only if it removes the last reference. When an object's reference count drops to 0, CPython frees it right away, inside the del.

Why isn't my object freed after del?

Something else still refers to it, often another object it points to in turn. A reference cycle keeps every count above 0, so only the cycle collector can free it.

What does gc.collect() do?

It runs the cycle collector now. It finds groups of objects that only refer to each other and frees them; objects freed by reference counting never needed it.

Verified: this timeline matches a real program, checked in CI on Python 3.14, 3.15 and free-threaded 3.15t. How we verify. Unclear or wrong? Tell us