Introduction
Memory leaks in Python can silently degrade performance, especially under production load. This guide walks you through diagnosing, fixing, and monitoring leaks so your services stay responsive.
Common Causes
-
Unreleased resources (files, sockets) without proper
close(). -
Reference cycles involving objects with
__del__. - Large caches that grow unchecked.
- Third‑party libraries that keep global state.
Step‑by‑Step Troubleshooting
-
Enable
tracemallocto capture allocation snapshots.
import tracemalloc
tracemalloc.start()
# ... run your workload ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
-
Inspect object graphs with
objgraph.
import objgraph
objgraph.show_most_common_types(limit=10)
objgraph.show_backrefs([leaking_obj], filename='leak.png')
- Force garbage collection to see what remains.
import gc
gc.collect()
print('Unreachable objects:', len(gc.garbage))
-
Use memory profilers (e.g.,
memory_profiler).
pip install memory_profiler
mprof run my_app.py
mprof plot
Proven Fixes
- Context managers for deterministic cleanup.
with open('data.txt') as f:
data = f.read() # file is closed automatically
-
Limit cache size with
functools.lru_cacheor custom eviction.
from functools import lru_cache
@lru_cache(maxsize=128)
def compute(value):
return heavy_calculation(value)
- Break reference cycles by using weak references.
import weakref
class Node:
def __init__(self, name):
self.name = name
self.parent = None
self.children = []
def set_parent(self, parent):
self.parent = weakref.ref(parent)
- Explicitly delete large objects when they are no longer needed.
large_blob = load_big_dataset()
process(large_blob)
# Release memory immediately
del large_blob
gc.collect()
Monitoring in Production
- Export process memory usage to Prometheus via
psutil.
import psutil, time
while True:
mem = psutil.Process().memory_info().rss / (1024 * 1024)
# push `mem` to a Prometheus gauge here
time.sleep(30)
- Set alerts for RSS growth beyond a threshold.
Resources
By following these steps, you can pinpoint the root cause of a Python memory leak, apply robust fixes, and keep your production systems healthy.
Top comments (0)