0
0
PythonHow-ToBeginner · 4 min read

How Python Manages Memory: Simple Explanation and Examples

Python manages memory using reference counting to track object usage and automatically frees memory when objects are no longer needed. It also uses a garbage collector to clean up cyclic references and a private memory allocator to optimize memory allocation.
📐

Syntax

Python does not require explicit syntax to manage memory because it handles memory automatically. However, understanding key functions related to memory management helps:

  • id(object): Returns the memory address of an object.
  • sys.getrefcount(object): Shows how many references point to an object.
  • gc.collect(): Manually triggers garbage collection.
python
import sys
import gc

x = []
print('Memory address of x:', id(x))
print('Reference count of x:', sys.getrefcount(x))

# Manually trigger garbage collection
collected = gc.collect()
print('Garbage collector: collected', collected, 'objects')
Output
Memory address of x: 140353123456784 Reference count of x: 2 Garbage collector: collected 0 objects
💻

Example

This example shows how Python increases and decreases reference counts as variables point to the same object, and how garbage collection can be triggered.

python
import sys
import gc

a = []
print('Initial ref count:', sys.getrefcount(a))  # Usually 2 (one from getrefcount argument, one from 'a')
b = a
print('Ref count after b = a:', sys.getrefcount(a))
del b
print('Ref count after del b:', sys.getrefcount(a))

# Create a cycle
class Node:
    def __init__(self):
        self.ref = self

node = Node()
print('Garbage collector before deleting node:', gc.collect())
del node
print('Garbage collector after deleting node:', gc.collect())
Output
Initial ref count: 2 Ref count after b = a: 3 Ref count after del b: 2 Garbage collector before deleting node: 0 Garbage collector after deleting node: 1
⚠️

Common Pitfalls

One common mistake is assuming Python immediately frees memory when variables are deleted. Python uses reference counting, so memory is freed only when no references remain. Also, cyclic references can cause memory leaks if not handled by the garbage collector.

Another pitfall is holding references unintentionally, which prevents memory from being freed.

python
import gc

class Cycle:
    def __init__(self):
        self.ref = self

c = Cycle()
del c
print('Garbage collector run:', gc.collect())  # Cleans up the cycle

# Wrong: holding reference unintentionally
lst = []
lst.append(lst)  # Creates a cycle
print('Garbage collector run:', gc.collect())  # Cleans up cycle

# Right: break cycle manually
lst.clear()
print('Garbage collector run after clearing:', gc.collect())
Output
Garbage collector run: 1 Garbage collector run: 1 Garbage collector run after clearing: 0
📊

Quick Reference

ConceptDescription
Reference CountingTracks how many references point to an object; frees memory when count is zero.
Garbage CollectionDetects and cleans up cyclic references that reference counting misses.
Memory AllocatorPython uses a private allocator to manage small objects efficiently.
sys.getrefcount()Returns the current reference count of an object.
gc.collect()Manually triggers garbage collection to free unreachable objects.

Key Takeaways

Python uses reference counting to automatically free memory when objects are no longer referenced.
Garbage collection handles cycles that reference counting alone cannot clean up.
You can inspect reference counts with sys.getrefcount() and trigger garbage collection with gc.collect().
Unintentional references or cycles can delay memory freeing and cause leaks.
Python’s private memory allocator optimizes small object memory management.