Overview of TCMalloc
mastermalloc() and C++'s operator new. It is designed for high-performance memory allocation in C and C++ applications.repository·master·Indexed 26 days ago
https://github.com/google/tcmallocA high-performance, multi-threaded memory allocator implementation of C's malloc() and C++'s operator new developed by Google. It features a three-layer architecture consisting of a front-end (per-CPU or per-thread caches), a middle-end (Transfer Cache and CentralFreeList), and a back-end (PageHeap or Hugepage Aware Allocator). The library is built using Bazel or CMake and depends on Abseil.
malloc() and C++'s operator new. It is designed for high-performance memory allocation in C and C++ applications.TCMalloc manages the heap using the following concepts:
Span is a contiguous run of one or more pages. A span can either manage a single large object or a sequence of small objects of a specific size-class.Span they belong to, allowing the allocator to identify the size-class or span for any given object address.For small objects, spans use an unrolled linked list with two-byte indexes to reduce cache misses and improve memory efficiency.
Temeraire is a hugepage-aware page heap for TCMalloc designed to better handle memory backed by hugepages. Its statistics provide a detailed breakdown of how memory is distributed across various caches to avoid breaking up hugepages.
The summary shows the number of different sizes of ranges, total MiB available, and total MiB of unmapped ranges.
Each line for a specific number of contiguous pages includes:
Temeraire is a hugepage-aware allocator designed to optimize memory usage by packing allocations into the smallest possible set of hugepages. It uses a tiered allocation strategy based on request size:
HugePageFiller.HugeRegion slabs (currently 1 GiB) that can cross hugepage boundaries.HugeAllocator or HugeRegion.Deallocation identifies which tier the object belonged to and marks it as free.
The middle-end acts as the intermediary between the front-end (per-thread/per-CPU caches) and the back-end (pageheap). It consists of two main components:
Spans. It satisfies requests by extracting objects from spans or requesting new spans from the back-end if existing ones are insufficient.Note: Both the transfer cache and central free list use mutex locks, which introduces serialization costs when accessing them.
There are two distinct projects based on Google's internal TCMalloc:
This repository (google/tcmalloc): This is Google's current implementation used in production. It focuses strictly on the memory allocator implementation itself and includes modern optimizations like per-CPU caches, sized delete, and a hugepage-aware backend.
gperftools: A community-adopted version that includes the memory allocator plus additional tools like a CPU profiler and a heap checker.
Use this repository if you want the latest implementation used by Google's C++ programs, which is optimized for modern platforms and based on Abseil.
In Per-Thread mode, TCMalloc assigns a thread-local cache to each thread.
In Temeraire-enabled TCMalloc, HugeRegion (and HugeRegionSet) is a core component used to manage large allocations that exceed a single hugepage size. It solves the 'trilemma' of supporting arbitrary allocation sizes, backing the heap with hugepages, and minimizing global space overhead.
HugeRegion allows the allocator to use the unused tail of a hugepage from one large allocation as the beginning of another contiguous large allocation. This prevents significant space overhead (up to 100%) that would occur if every allocation larger than a hugepage were forced to round up to a full hugepage boundary.
TCMalloc manages memory using one of two caching modes to avoid lock contention during allocation and deallocation:
The back-end manages large unused memory chunks, fetches memory from the OS, and returns unused memory to the OS. There are two types:
man rseq(2)). This mechanism allows TCMalloc to fetch from or return elements to a per-CPU array without using locking or atomic instructions. If a thread is interrupted (e.g., via a context switch) while executing a restartable sequence, the sequence is restarted from the top, ensuring atomicity without contention.TCMalloc implements per-CPU caches using the Linux kernel's restartable sequences (rseq(2)) mechanism. This allows TCMalloc to execute code regions atomically with respect to other threads on the same CPU by avoiding expensive atomic operations in the common case.
If a thread is preempted, interrupted by a signal, or migrated to a different core while executing an rseq sequence, the kernel aborts the sequence and restarts it. To support this, TCMalloc code paths are designed so that the entire sequence—except for the final 'commit' store to memory—can be safely restarted. This design optimizes performance by staying on the same core and avoiding atomics, accepting the rare cost of a restart when preemption occurs.