Lab 04: Memory Allocator
Overview
Step 1: CPython Memory Architecture
import sys
# CPython pymalloc: arenas → pools → blocks
# - Arenas: 256 KB chunks allocated from OS
# - Pools: 4 KB within arenas, one size class per pool
# - Blocks: fixed-size within pools (8, 16, 24, ... 512 bytes)
# Objects > 512 bytes go directly to the system allocator
# getsizeof returns the object's own memory (not referenced objects)
data = [1, 2, 3, 4, 5]
print(f"List (5 ints) getsizeof: {sys.getsizeof(data)} bytes")
print(f" Note: doesn't include the ints themselves")
# Recursive size calculation
def deep_sizeof(obj, seen=None):
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
seen.add(obj_id)
size = sys.getsizeof(obj)
if isinstance(obj, dict):
size += sum(deep_sizeof(k, seen) + deep_sizeof(v, seen) for k, v in obj.items())
elif isinstance(obj, (list, tuple, set)):
size += sum(deep_sizeof(item, seen) for item in obj)
return size
nested = {'users': [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]}
print(f"\nNested dict getsizeof: {sys.getsizeof(nested)} bytes")
print(f"Nested dict deep_sizeof: {deep_sizeof(nested)} bytes")Step 2: tracemalloc — Memory Profiling
tracemalloc — Memory ProfilingStep 3: Snapshot Comparison
Step 4: gc Module — Cyclic Garbage Collector
gc Module — Cyclic Garbage CollectorStep 5: gc.get_referrers — Finding What Holds References
gc.get_referrers — Finding What Holds ReferencesStep 6: weakref — Cache Without Preventing Collection
weakref — Cache Without Preventing CollectionStep 7: Memory Leak Detection Pattern
Step 8: Capstone — Memory Profiler Decorator
Summary
Concept
API
Use Case
Last updated
