Why is the first C++ (m)allocation always 72 KB?
A curious C++ developer uncovers why the very first allocation in a C++ program is consistently 72 KB, a persistent mystery for those working with custom memory allocators. It turns out libstdc++ preemptively reserves an 'emergency pool' for exception handling, a subtle but crucial detail for system-level debugging and understanding C++ runtime behavior. This deep dive into a common but opaque system quirk resonates with HN's audience who appreciate unraveling low-level technicalities.
The Lowdown
The author, while developing custom memory allocators and debugging their behavior, consistently observed a curious phenomenon: the very first C++ memory allocation was always 72 KB. This article chronicles their journey to unravel this mystery, highlighting the tools and techniques used to trace the allocation back to its source.
- The investigation began by using a custom
LD_PRELOADmalloc wrapper with logging, and thengdbto inspect the call stack of the first 72 KB allocation. - The backtrace pointed to
libstdc++.so.6, specifically to__gnu_cxx::__pool_alloc_base::_M_allocate_chunk. - Further drilling down into the
libstdc++source code, the allocation was pinpointed tolibsupc++/eh_alloc.cc, revealing it's for an "emergency pool" used in exception handling. - This emergency pool ensures that exceptions can still be allocated and thrown even if the primary
mallocfails, acting as a critical fallback mechanism. - The 72 KB size is derived from internal
libstdc++tunables likeEMERGENCY_OBJ_SIZEandEMERGENCY_OBJ_COUNT, which are based on system word size and can be modified viaGLIBCXX_TUNABLES. - The author demonstrates how changing these tunables alters the initial allocation size, confirming the emergency pool's role.
- This finding also sheds light on confusing Valgrind reports where this memory was often marked as "still reachable," a behavior addressed in newer Valgrind versions by explicitly freeing the pool during program shutdown.
This deep dive demonstrates the intricate dance of memory management within the C++ runtime, where seemingly arbitrary behaviors like an initial 72 KB allocation are in fact carefully designed low-level system safeguards. It serves as a testament to the complexity and hidden mechanisms beneath everyday programming.