# sl_alloc

### C LIBRARY

sl_alloc

### C LIBRARY SUMMARY

A memory allocator for short lived memory blocks in the Erlang Run-Time System (ERTS internal library).

### DESCRIPTION

This page mainly describes `sl_alloc` release 2 which is enabled by default. See System Flags Affecting sl_alloc on how to enable `sl_alloc` release 1.

The main idea behind `sl_alloc` is to use one allocator for short lived memory blocks and another allocator which puts more effort in finding a good fit (perhaps the best fit) for long lived memory blocks. The other allocator is expected to do a much better job with the long lived memory blocks when it is not disturbed by short lived blocks with less fragmentation in the areas where long lived blocks are placed as a result. Putting more effort in finding a good fit for long lived memory blocks than short lived is more rewarding since it will have a longer effect. By putting less effort in finding a good fit for short lived memory blocks the CPU load will decrease. The fragmentation in these areas is expected to increase, but as long as it is kept on a reasonable level the overall fragmentation can be reduced at the same time as the CPU load is reduced.

`sl_alloc` manages multiple areas, called carriers, in which memory blocks are placed. A carrier is either placed in a memory segment created by a call to the system call `mmap()` or in the heap segment (by a call to `malloc()`). Multiblock carriers are used for storage of several small blocks, and singleblock carriers are used for storage of one large block.

A "good fit" algorithm is used for management of blocks in multiblock carriers. Segregated free lists with a maximum search depth (in each list) are used in order to find a good fit fast. Boundary tags (headers and footers) in free blocks are used for fast coalescing.

The other allocator (typically `malloc()`) will normally manage the heap segment. By placing `sl_alloc` carriers in memory segments created by `mmap()`, `sl_alloc` will disturb the other allocator as little as possible. Really large requests to `sl_alloc` are placed in singleblock carriers in order to avoid creating really large holes. The downside of this is an increased number of `mmap/munmap` calls which can give a performance penalty.

`sl_alloc` release 1 only manages singleblock carriers, that is, blocks that are placed in multiblock carriers by `sl_alloc` release 2 are allocated by `malloc()` in release 1.

Mainly Erlang heap data (Erlang heaps, and message buffers) has been classified as short lived, and most of the other data has been classified as long lived. Erlang heap data has been classified as short lived because it is frequently moved between memory blocks due to copying garbage collection.

"Other data" that may consume large amounts of memory is mainly ETS data and large binaries. ETS data and large binary data have been classified as long lived since the data will not be moved until it is removed.

One cannot say that all ETS and binary data are long lived and all Erlang heap data is short lived, but it should be safe to say that most ETS and binary data are more long lived than most Erlang heap data.

The use of `sl_alloc` mainly has an advantage when there is a significant amount of ETS and/or binary data since `malloc` will be able to do a better job with this data when it does not have to bother with the Erlang heap data.

If almost all data in the system is being stored on the process heaps, the situation is not as good since the main part of the memory will be allocated by `sl_alloc` which probably fragments the memory more than `malloc`. The situation is not as bad as it seems though. When the data is stored on Erlang heaps it will be stored in larger but fewer blocks than if it had been stored in ETS tables which simplifies the job for `sl_alloc`. `sl_alloc` is also quite good at preventing fragmentation even though `malloc` probably is better. When memory consumption decreases heavily, `sl_alloc` decreases the total amount of used pages far better than a `malloc` implementation only using the heap segment. `sl_alloc` also still has the advantage of reducing CPU load compared to a `malloc` implementation that is putting more effort in finding a good fit. But in the case that the memory consumed mainly consist of Erlang heap data, the `malloc` implementation used causes a lot less fragmentation than `sl_alloc`, and there is a memory shortage, it may be best not to enable `sl_alloc` release 2.

### System Flags Affecting sl_alloc

| Only use these flags if you are absolutely sure what you are doing. Unsuitable settings may cause serious performance degradation (and even a system crash) at any time during operation.

The following `sl_alloc` flags can be passed to the Erlang virtual machine (see also erl(1)):

+Se BOOL
  Enable `sl_alloc` (default true if `mmap()` is available; otherwise, false).
+Sr RELEASE
  Enable a specific release of `sl_alloc` (default 2). Currently release 1 (version 1.0) and release 2 (version 1.9.3) can be enabled.
+Ssbct SIZE_IN_KB
  Singleblock carrier threshold (default 128 Kb). Blocks larger than this threshold will be placed in singleblock carriers.
+Smmc AMOUNT
  Max mmap carriers (default 64). Maximum number of carriers placed in memory segments created by `mmap()`. When this limit has been reached, new carriers will be placed on the heap segment (by using `malloc()` instead of `mmap()`).
+Ssbcmt RATIO
  Singleblock carrier move threshold (default 80%). A block in a singleblock carrier which is resized by `sl_realloc()` will be left in an unchanged singleblock carrier if the block fits, the ratio of unused memory (in percent) is less than this threshold, and a (copying) move will be avoided; otherwise, it will be moved into a new singleblock carrier or into a multiblock carrier.
+Smcs SIZE_IN_KB
  Main carrier size (default 1.25 Mb). The size of the main multiblock carrier. The main multiblock carrier is placed in the heap segment and is never removed.
+Sscs SIZE_IN_KB
  Smallest multiblock carrier size (default 1.25 Mb). The size of the first multiblock carrier if no main carrier exist (that is, if the "main carrier size" is 0).
+Slcs SIZE_IN_KB
  Largest multiblock carrier size (default 50 Mb). The maximum size of a multiblock carrier.
+Scgr RATIO
  Multiblock carrier growth ratio (default 25%). The ratio of growth in size of multiblock carriers when the number of carriers increases. The size of a multiblock carrier is based on the "smallest multiblock carrier size", the number of existing multiblock carriers, and the "multiblock carrier growth rate".
+Smbsd DEPTH
  Max block search depth (default 3). Free blocks are placed in segregated free lists which are searched when trying to satisfy a request. Each free list contains blocks of sizes in a specific range. The max block search depth sets a limit on the maximum number of blocks to inspect in a free list during the search.
+Sb BOOL
  Use `sl_alloc` for binaries (default false). When turned on (true), binaries (not allocated on Erlang heaps) will be allocated with `sl_alloc`. When turned off (false), binaries (not allocated on Erlang heaps) will be allocated by `malloc`.

| Most of these flags are highly implementation dependent, and they may be changed or removed without prior notice. `sl_alloc` is not obliged to strictly use the settings that has been passed to it. The `+Ssbcmt`, `+Smmc`, `+Smcs`, `+Sscs`, `+Slcs`, and `+Smbsd` flags will be silently ignored when `sl_alloc` release 1 is enabled.

### See Also

erl(1)

### AUTHORS

Rickard Green - support@erlang.ericsson.se

erts 5.2.3.3
Copyright © 1991-2003 Ericsson Utvecklings AB