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:

  1. __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).
  2. 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.