What Does sys.getsizeof Measure in Python?
Python's sys.getsizeof() function returns the memory
footprint of an object in bytes, accounting for the object's internal
structure and garbage collection overhead. However, it only performs a
shallow measurement: it computes the memory directly allocated to the
object itself, ignoring the memory consumed by any objects it
references. Understanding this distinction is critical for accurately
diagnosing memory usage in Python applications.
Direct Memory vs. Referenced Memory
When you pass an object to sys.getsizeof(), it returns
the storage required for that specific object instance. For primitive
types—such as integers, floats, and strings—this value represents the
total memory consumption because the object directly contains its value
alongside internal metadata like reference counts and type pointers.
For container types, such as lists, dictionaries, tuples, and sets,
sys.getsizeof() measures only the container structure
itself. For example, calling sys.getsizeof() on a list
calculates the space used by the list header and an internal array of
memory addresses (pointers). It does not measure the items stored within
the list. A list containing ten 100-megabyte strings will report
virtually the same size as a list containing ten small integers, because
the list only holds pointers to those objects, not the objects
themselves.
How
sys.getsizeof() Works Internally
The function operates by calling the object's internal
__sizeof__() method and adding any additional
implementation-specific overhead:
__sizeof__()Implementation: Each built-in type defines a__sizeof__()method that calculates its base size plus any variable-length data (such as characters in a string or pointer slots in an array).- Garbage Collector Overhead: If the object is
managed by Python's cyclic garbage collector (such as lists, dicts, and
custom class instances),
sys.getsizeof()automatically adds the size of the garbage collector header (PyGC_Head) to the total.
Behavior with Custom Classes
When applied to instances of user-defined classes,
sys.getsizeof() measures only the instance object itself.
By default, user-defined instances store their attributes in an internal
dictionary (__dict__). The size returned will not include
the memory consumed by the __dict__ object or the values
stored inside it.
If a class uses __slots__ instead of a dynamic
dictionary, the attributes are stored directly in the instance layout.
In this case, sys.getsizeof() reflects the space allocated
for these fixed attribute pointers, but it still excludes the memory of
the referenced objects assigned to those attributes.
Measuring Deep Memory Usage
Because sys.getsizeof() does not recursively traverse
nested structures, it cannot provide an accurate total footprint for
complex, nested data structures. To calculate the full ("deep") memory
usage of an object and everything it references, you must recursively
traverse the object graph using tools like the asizeof
module from the third-party Pympler library or custom
recursive traversal algorithms.