Python application creating millions of small objects (e.g., tree nodes, graph vertices, data records) consuming excessive memory. The metric was peak RSS. Baseline used regular Python classes which allocate a __dict__ (hash table) per instance to store attributes, consuming ~104 bytes overhead per object even for a class with just two int attributes.
Declaring __slots__ on the class eliminates the per-instance __dict__, storing attributes in a fixed-size tuple-like structure at the C level. This reduces per-instance memory from ~232 bytes (dict-based) to ~72 bytes for a two-attribute object — a 69% reduction.
For a graph with 10M nodes (id: int, weight: float, visited: bool), __slots__ reduced memory from 2.9 GB to 0.84 GB.
| Class Style | Bytes/Instance | 10M Instances (GB) |
|---|---|---|
| Regular class (with dict) | 296 | 2.90 |
| slots class | 88 | 0.84 |
| NamedTuple | 80 | 0.76 |
| dataclass(slots=True) (3.10+) | 88 | 0.84 |
__slots__on classes that need dynamic attributes:__slots__removes__dict__, so you can't add attributes at runtime (obj.new_attr = xraisesAttributeError). Adding'__dict__'to__slots__brings back the dict and defeats the purpose.- Forgetting
__slots__on parent classes: If any base class lacks__slots__, instances still get__dict__from the base. All classes in the hierarchy must declare__slots__.
# Regular class: ~296 bytes per instance
class Node:
def __init__(self, id, weight, visited=False):
self.id = id
self.weight = weight
self.visited = visited
# Slots class: ~88 bytes per instance (69% reduction)
class Node:
__slots__ = ('id', 'weight', 'visited')
def __init__(self, id, weight, visited=False):
self.id = id
self.weight = weight
self.visited = visited
# Python 3.10+ dataclass with slots
from dataclasses import dataclass
@dataclass(slots=True)
class Node:
id: int
weight: float
visited: bool = FalseCPython 3.10+ (for dataclass(slots=True)). __slots__ itself works in all CPython versions. Memory measured with tracemalloc and sys.getsizeof(). Does not apply to PyPy (which uses a different object model that's already memory-efficient).