Arena allocations

Both the small and the large portions of the allocator allocate and deallocate memory from the system in the form of arena chunks by calling mmap() and munmap().

By default, the arena allocations are performed in 32 KB chunks. This value is specified by one of the following:

  • a global variable that's defined in the allocator, but can be redefined or modified in the application
  • the _amblksiz global variable

This value must be a multiple of 4 KB, and currently is limited to being less than 256 KB. You can also configure this parameter by setting the MALLOC_ARENA_SIZE environment variable, or by calling mallopt() with MALLOC_ARENA_SIZE as the command.

For example, if you want to change the arena size to 16 KB, do one of the following:

  • _amblksiz = 16384;
  • export MALLOC_ARENA_SIZE=16384
  • mallopt(MALLOC_ARENA_SIZE, 16384);

Environment variables are checked only at program startup, but changing them is the easiest way of configuring parameters for the allocator so that these parameters are used for allocations that occur before main().

The allocator also attempts to cache recently used arena blocks. This cache is shared between the small- and the large-block allocator. You can configure the arena cache by setting the following environment variables:

MALLOC_ARENA_CACHE_MAXBLK
The number of cached arena blocks.
MALLOC_ARENA_CACHE_MAXSZ
The total size of the cached arena blocks.

Alternatively, you can call:

mallopt(MALLOC_ARENA_CACHE_MAXSZ, size);
mallopt(MALLOC_ARENA_CACHE_MAXBLK, number);

You can tell the allocator to never release memory back to the system from its arena cache by setting the environment variable:

export MALLOC_MEMORY_HOLD=1

or by calling:

mallopt(MALLOC_MEMORY_HOLD, 1);

Once you've changed the values by using mallopt() for either MALLOC_ARENA_CACHE_MAXSZ or MALLOC_ARENA_CACHE_MAXBLK, you must call mallopt() to cause the arena cache to be adjusted immediately:

// Adjust the cache to the current parameters or
// release all cache blocks, but don't change parameters
mallopt(MALLOC_ARENA_CACHE_FREE_NOW, 0);
mallopt(MALLOC_ARENA_CACHE_FREE_NOW, 1);

Without a call with a command of MALLOC_ARENA_CACHE_FREE_NOW, the changes made to the cache parameters will take effect whenever memory is subsequently released to the cache.

So for example, if the arena cache currently has 10 blocks, for a total size of say 320 KB, and if you change the arena parameters to MALLOC_ARENA_CACHE_MAXBLK = 5 and MALLOC_ARENA_CACHE_MAXSZ = 200 KB, an immediate call to mallopt(MALLOC_ARENA_CACHE_FREE_NOW, 0) will reduce the cache so that the number of blocks is no more than 5, and the total cache size is no more than 320 KB. If you don't make the call to mallopt(), then no immediate changes are made. If the application frees some memory, causing a new arena of size 32 KB to get released to the system, this will not be cached, but will be released to the system immediately.

You can use MALLOC_ARENA_CACHE_MAXSZ and MALLOC_ARENA_CACHE_MAXBLK either together or independently. A value of zero is ignored.

You can preallocate and populate the arena cache by setting the MALLOC_MEMORY_PREALLOCATE environment variable to a value that specifies the size of the total arena cache. The cache is populated by multiple arena allocation calls in chunks whose size is specified by the value of MALLOC_ARENA_SIZE.

The preallocation option doesn't alter the MALLOC_ARENA_CACHE_MAXBLK and MALLOC_ARENA_CACHE_MAXSZ options. So if you preallocate 10 MB of memory in cache blocks, to ensure that this memory stays in the application throughout the lifetime of the application, you should also set the values of MALLOC_ARENA_CACHE_MAXBLK and MALLOC_ARENA_CACHE_MAXSZ to something appropriate.