advanced

Garbage Collection & Memory Management

7 min read

Overview

Python automatically manages memory allocation and deallocation. You don't have to manually free memory like in C or C++. Memory management in CPython is handled primarily through Reference Counting supplemented by a Cyclic Garbage Collector.

Learning Objectives

  • Understand reference counts and how objects are destroyed when their reference count drops to 0.
  • Learn why circular references require Python's cyclic garbage collector (gc).
  • Inspect reference counts using sys.getrefcount().

Concept Explanation

In simple words:

  1. Reference Counting: Every Python object tracks how many variables point to it.
    • When you assign b = a, reference count increases (+1).
    • When a variable goes out of scope or is deleted (del a), reference count decreases (-1).
    • When reference count reaches 0, memory is freed immediately!
  2. Cyclic Garbage Collector: If Object A points to Object B, and Object B points back to Object A (a circular loop), their reference counts never reach 0. Python's gc module periodically scans for these orphaned reference loops and reclaims their memory.

Code Examples

Example 1 — Reference Counting in Action

python
import sys

class DataBuffer:
    def __init__(self, name):
        self.name = name

# Create object
buf = DataBuffer("StreamBuffer")

# Inspect reference count (getrefcount adds 1 temporary reference)
print("Reference Count:", sys.getrefcount(buf) - 1) # 1

alias = buf
print("Reference Count after alias:", sys.getrefcount(buf) - 1) # 2

del alias
print("Reference Count after del:", sys.getrefcount(buf) - 1) # 1

Example 2 — Cyclic Reference & gc Module

python
import gc

class Node:
    def __init__(self, value):
        self.value = value
        self.ref = None

# Create circular reference loop
node_a = Node("A")
node_b = Node("B")
node_a.ref = node_b
node_b.ref = node_a

# Delete global variable names
del node_a
del node_b

# Force garbage collection cycle
collected = gc.collect()
print(f"Unreachable cyclic objects collected: {collected}")

Visual Flow

The following execution flow represents how Python reclaims memory:

⚡ Visual Execution Flow
Variable Scope Ends / delRef Count Drops to 0Immediate DeallocationCyclic GC Scans Gen 0/1/2 for Cycles

Common Mistakes

  • Disabling Garbage Collection in Production: Disabling gc.disable() without understanding reference cycles can cause severe memory leaks in long-running applications.

Best Practices

  • Let Python's reference counting handle memory automatically.
  • Use weakref references when building complex graphs or caches to prevent circular reference cycles.