Python28 min read
Python Memory Management
Understand how Python manages memory, when objects are freed, why generators save memory, and how to avoid common memory-heavy patterns.
David Miller
July 27, 2025
5.3k251
Python manages memory automatically, but as your programs grow, you must understand memory basics to avoid crashes and slowdowns.
This lesson will help you build a strong mental model.
## The big idea
When you create objects (lists, dicts, class instances), they live in memory.
Python frees memory when objects are no longer referenced.
Key mechanisms:
- reference counting
- garbage collection (for cycles)
## Reference counting (simple example)
```python
a = [1, 2, 3]
b = a # now two variables reference the same list
del a # list still exists because b still references it
```
The object is freed only when references drop to zero.
## Memory size comparison (list vs tuple)
```python
import sys
x = [1, 2, 3, 4, 5]
y = (1, 2, 3, 4, 5)
print(sys.getsizeof(x))
print(sys.getsizeof(y))
```
Tuples often use less memory because they are immutable and simpler internally.
## Garbage collection (cycles)
Sometimes objects reference each other in a loop (cycle). Reference counting alone can’t clean that, so Python uses garbage collection.
```python
import gc
print(gc.isenabled())
gc.collect() # force cleanup
```
## Big memory mistake: building huge lists
```python
# memory heavy
nums = [i for i in range(10_000_000)]
print(nums[0], nums[-1])
```
Better: generator (lazy)
```python
# memory friendly
nums = (i for i in range(10_000_000))
print(next(nums))
```
## Why generators help (concept)
A list stores ALL values.
A generator produces one value at a time.
## __slots__ to reduce object memory (advanced but practical)
```python
class Person:
__slots__ = ["name", "age"]
def __init__(self, name, age):
self.name = name
self.age = age
```
This removes the normal per-object __dict__, saving memory when you create many instances.
## Weak references (prevent memory leaks)
```python
import weakref
class Data:
def __init__(self, value):
self.value = value
obj = Data(42)
ref = weakref.ref(obj)
print(ref().value)
del obj
print(ref()) # None
```
## Graph: list vs generator memory model
```mermaid
flowchart LR
A[List] --> B[Allocates all items in memory]
C[Generator] --> D[Produces one item at a time]
D --> E[Low memory usage]
```
## Key points
- Python frees objects when references end
- Garbage collector handles cycles
- Generators reduce memory for large data
- __slots__ helps when you create many objects
- Weak references can prevent certain memory issues
#Python#Advanced#Memory