Fundamentals 12 min read

Understanding Python’s Object Model: References, Refcounts, and Garbage Collection

This article explains Python’s memory management by exploring how objects and references work, demonstrating reference counting, the role of the id() function, the impact of object caching, and how Python’s garbage collector handles reference cycles through generation-based collection.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Understanding Python’s Object Model: References, Refcounts, and Garbage Collection

Introduction

Memory management is a crucial aspect of language design that directly affects performance. Using Python as an example, we illustrate how a dynamic, object‑oriented language manages memory.

Object Memory Usage

Even the simplest assignment creates a reference to an object. In Python, the statement a = 1 binds the name a to the integer object 1. Python separates objects from references, similar to using chopsticks to pick up food. a = 1 The built‑in id() function returns the identity (memory address) of an object.

a = 1
print(id(a))
print(hex(id(a)))

On my machine the output is:

11246696
'0xab9c68'

Python caches small integers and short strings, so multiple references to the same value point to the same object.

a = 1
b = 1
print(id(a))
print(id(b))
print(a is b)  # True
a = "good"
b = "good"
print(a is b)  # True (cached)

a = "very good morning"
b = "very good morning"
print(a is b)  # False (not cached)

a = []
b = []
print(a is b)  # False

Reference Counting

Every object maintains a reference count. The sys.getrefcount() function shows this count, noting that passing the object as an argument adds a temporary reference.

from sys import getrefcount
a = [1, 2, 3]
print(getrefcount(a))
b = a
print(getrefcount(b))

When another object references a, its count increases:

a = [1, 2, 3]
print(getrefcount(a))
b = [a, a]
print(getrefcount(a))

Objects Referencing Objects

Container objects (lists, dicts, etc.) store references to their elements, not the elements themselves. A custom class can also hold references:

class from_obj(object):
    def __init__(self, to_obj):
        self.to_obj = to_obj

b = [1, 2, 3]
a = from_obj(b)
print(id(a.to_obj))
print(id(b))

The global namespace dictionary ( globals()) also holds references to objects.

Reference Cycles

Mutual references can create cycles that the simple reference‑counting collector cannot reclaim. The third‑party objgraph package can visualize these relationships.

x = [1, 2, 3]
y = [x, dict(key1=x)]
z = [y, (x, y)]
import objgraph
objgraph.show_refs([z], filename='ref_topo.png')

To install:

sudo apt-get install xdot
sudo pip install objgraph

Reducing References

The del statement removes a reference, decreasing the count. Deleting an element from a container also reduces the count.

from sys import getrefcount
a = [1, 2, 3]
b = a
print(getrefcount(b))
del a
print(getrefcount(b))

a = [1,2,3]
del a[0]
print(a)

Garbage Collection

When an object's reference count drops to zero, it becomes garbage and can be reclaimed. Python triggers garbage collection only when the difference between allocated and deallocated objects exceeds a threshold.

import gc
print(gc.get_threshold())  # (700, 10, 10)
print(gc.get_count())
# Manual collection
gc.collect()

The threshold can be adjusted with gc.set_threshold().

import gc
gc.set_threshold(700, 10, 5)

Generation‑Based Collection

Python groups objects into three generations (0, 1, 2). New objects start in generation 0. Objects that survive a collection are promoted to the next generation. The second and third numbers in the threshold (10, 10) control how often older generations are scanned.

Isolated Reference Cycles

Even if all external references to a cyclic group are deleted, the objects remain because their internal references keep the count above zero. Python resolves this by temporarily copying reference counts ( gc_ref) and decrementing them for each outgoing reference; objects whose gc_ref reaches zero are reclaimed.

a = []
b = [a]
a.append(b)
# Now a and b reference each other
# Deleting external names
del a
del b
# The cycle is still present until the cyclic GC runs

Conclusion

Python separates objects from references, uses reference counting as its primary memory‑management strategy, and supplements it with a generational garbage collector to handle reference cycles. Understanding these mechanisms is essential for writing efficient Python code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonGarbage Collectionreference counting
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.