PyObject C-Struct & Dynamic Typing Overhead
1Concept
Every Python object in CPython is wrapped in a C `PyObject` structure containing `ob_refcnt` (reference counter) and `ob_type` (type descriptor pointer). An integer `42` in Python occupies 28 bytes in RAM compared to 4 bytes in C.
2Architecture Diagram
+-------------------------------------------------------------+ | CPython PyObject Structure Header (28 Bytes total for int) | | +---------------------------+---------------------------+ | | | ob_refcnt (8 Bytes) | ob_type (*PyTypeObject) | | | +---------------------------+---------------------------+ | | | ob_digit / Value payload (12 Bytes) | | | +-------------------------------------------------------+ | +-------------------------------------------------------------+
3Code Example
Python 3.12
import sys
x = 42
text = "Hello Enterprise Python"
lst = [1, 2, 3]
print("=== Memory Allocation (sys.getsizeof) ===")
print(f"int (42): {sys.getsizeof(x)} bytes")
print(f"str ('{text}'): {sys.getsizeof(text)} bytes")
print(f"list ([1,2,3]): {sys.getsizeof(lst)} bytes")4Expected Output
=== Memory Allocation (sys.getsizeof) ===
int (42): 28 bytes
str ('Hello Enterprise Python'): 70 bytes
list ([1,2,3]): 88 bytes5Key Takeaways
- ✓All Python objects carry an 8-byte reference count and an 8-byte type pointer.
- ✓Dynamic typing requires pointer indirection for every method or attribute call.
- ✓Use NumPy arrays or __slots__ to eliminate PyObject overhead when processing millions of items.