đź§  How Does Python's Memory Management Work?

Bruno MarquesBruno Marques
3 min read

When we write Python code, we rarely stop to think about what happens under the hood. Variables, lists, dictionaries… everything “just works.” But what ensures that memory is used efficiently? How does Python know when it’s safe to free memory?

In this article — the seventh in my Python fundamentals series — we’ll explore how Python manages memory, including allocation, reference counting, garbage collection, and best practices to avoid memory leaks.


đź§± Key Concept: Everything is an Object

In Python, everything is an object: numbers, strings, functions, classes… Every object is stored in memory and managed by the interpreter.

Each object in memory holds:

  • Its type (e.g., int, str, list)

  • Its value (stored data)

  • A reference count

  • Other internal metadata


đź§® Reference Counting

At the core of Python’s memory management is reference counting. Every time you assign an object to a variable, its reference count increases.

When the reference is removed (e.g., a variable goes out of scope or is reassigned), the count decreases. When the count reaches zero, Python automatically deletes the object and reclaims the memory.

Example:

import sys

a = [1, 2, 3]
print(sys.getrefcount(a))  # Output: ~2 (one from 'a' and one from the function argument)
b = a
print(sys.getrefcount(a))  # Now ~3
del b
print(sys.getrefcount(a))  # Back to ~2

♻️ Garbage Collector

Reference counting alone can’t handle all cases — especially cyclic references.

Example of a cycle:

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

a = Node()
b = Node()

a.ref = b
b.ref = a

Even if a and b are deleted from the outer scope, they still reference each other. Their reference count never reaches zero.

That’s why Python includes a garbage collector that runs periodically to detect and clean up cycles.

You can inspect or manually trigger it using the gc module:

import gc

print(gc.isenabled())  # True
gc.collect()           # Manually trigger collection

📊 Generational Garbage Collection

To improve performance, Python categorizes objects into generations:

  • Generation 0: newly created objects

  • Generation 1: objects that survived one collection

  • Generation 2: long-lived objects

Older generations are collected less frequently, as they tend to be more stable and costly to inspect.


đź§Ľ Best Practices for Managing Memory

Even though Python does most of the work, following good practices can help avoid leaks and boost performance:

1. Avoid circular references

Prefer structures that don’t form cycles, or use weakref when needed.

import weakref

class Data:
    pass

d = Data()
r = weakref.ref(d)
print(r())  # Access the object

2. Explicitly clean up resources

When working with files, connections, or large objects, use context managers:

with open('file.txt') as f:
    data = f.read()

3. Watch out for global structures or unmanaged caches

Global variables that accumulate data can cause silent memory leaks over time.

4. Use memory profiling tools

Modules like tracemalloc, objgraph, or memory_profiler help you visualize memory usage and detect trouble spots.

import tracemalloc

tracemalloc.start()

# Code to measure
...

snapshot = tracemalloc.take_snapshot()
for stat in snapshot.statistics('lineno')[:5]:
    print(stat)

📌 Conclusion

Python’s memory management combines:

✅ Reference counting – to free memory as soon as objects are no longer needed
✅ Garbage collection – to handle cyclic references
✅ Generational strategy – to balance performance and efficiency

Understanding these mechanisms helps you write cleaner code, avoid memory leaks, and optimize your applications mindfully.


If you’re enjoying this Python fundamentals series, feel free to share it or leave feedback!

Next up: we'll explore dynamic and strong typing in Python — how does it really work in practice?

#Python #MemoryManagement #GarbageCollector #PythonTips #DevLife #CleanCode #PythonFundamentals

0
Subscribe to my newsletter

Read articles from Bruno Marques directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Bruno Marques
Bruno Marques