How to Drastically Reduce Python Object Memory Usage
This article explains why large numbers of active Python objects can cause memory problems and presents several techniques—including using dicts, class __slots__, namedtuple, recordclass, Cython, and NumPy—to shrink object size and dramatically lower memory consumption.
When many objects are active in memory, especially with limited RAM, Python programs can suffer memory issues. This article demonstrates techniques to shrink object size and dramatically reduce memory consumption.
Using dict
Representing a point with a {'x':1, 'y':2, 'z':3} dictionary occupies 240 bytes per instance; one million instances require about 240 MB.
ob = {'x':1, 'y':2, 'z':3}
x = ob['x']
ob['y'] = yClass instances
Defining a class with __init__ and storing attributes creates an instance size of 56 bytes for the __dict__, leading to roughly 168 MB for one million objects.
class Point:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
ob = Point(1, 2, 3)
x = ob.x
ob.y = yUsing __slots__
Adding __slots__ removes the per‑instance __dict__ and __weakref__, reducing size to 64 bytes (about 64 MB for one million instances).
class Point:
__slots__ = ('x', 'y', 'z')
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
ob = Point(1, 2, 3)
print(sys.getsizeof(ob)) # 64Tuples
Native tuples are more compact (72 bytes) but lack named field access.
ob = (1, 2, 3)
x = ob[0]
# ob[1] = y # ERROR – tuples are immutablenamedtuple
collections.namedtupleprovides named access with the same memory footprint as a plain tuple (72 bytes per instance).
from collections import namedtuple
Point = namedtuple('Point', ('x', 'y', 'z'))
ob = Point(1, 2, 3)
print(ob.x) # 1recordclass
recordclasscreates mutable named tuples with size 48 bytes, using about 48 MB for one million objects.
from recordclass import recordclass
Point = recordclass('Point', ('x', 'y', 'z'))
ob = Point(1, 2, 3)
ob.x = 10 # mutabledataobject
recordclass.dataobjectyields objects of 48 bytes without garbage‑collection overhead.
from recordclass import dataobject
class Point(dataobject):
x: int
y: int
z: int
ob = Point(1, 2, 3)
print(sys.getsizeof(ob)) # 40Cython
Defining a Cython class with cdef public int fields reduces instance size to 32 bytes (≈32 MB for one million instances).
cdef class Point:
cdef public int x, y, z
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
ob = Point(1, 2, 3)
print(sys.getsizeof(ob)) # 32NumPy
Using a NumPy structured dtype for the point and allocating an array of zeros stores each element in 12 bytes, resulting in about 12 MB for one million points.
import numpy as np
Point = np.dtype([('x', np.int32), ('y', np.int32), ('z', np.int32)])
points = np.zeros(1_000_000, dtype=Point)
print(points.nbytes) # 12,000,000 bytesThe article concludes that Python developers have multiple options to minimize memory usage of large numbers of objects.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
