BEAM Wisdoms — Virtual Machine Knowledge Base Help

BEAM Internal data sizes

Each boxed term has size described below plus one word for term value itself which you store somewhere else (be it on heap then you should count size for this term too, or in register/on stack - then it will not consume heap memory).

For specific bit positions and bit sizes please always refer to original beam sources, file: erl_term.h

Immediate

All immediate values have size of one Word.

They are: local pid, local port, small integer, atom, NIL (an empty list []) and catch (internal value). Continuation Pointer (CP) can also be considered an immediate, although it is a special value which only appears on stack and never in registers or heap.

List

List value is a pointer to cons cell. Cons cell has size of two Words (one for head, and another for tail). Cons cell can link to next cons cell and so on, until tail becomes a non-list term (for improper lists) or NIL (for proper lists).

Size of a list is 1 Word (for a pointer) and also on the heap 2*num_cells Words.

Boxed

Boxed value is a pointer to the heap or some other area and always takes 1 Words. A Box always points to a memory block which starts with a Header Tag (below) except during GC.

A Box always points to a Header except during GC. Header word typically contains an arity, which is stored in most-significant bits of their first word, following the header tag (which is 4+2 bits).

Header is a special tag which hides all sorts of internal opaque data. Header can be found on heap only and remaining most-significant bits usually represent its size (arity). For maps, arity is calculated using different formula ( see MAP_HEADER_ARITY macro).

By header tag headers can mark the beginning of: arityval (a tuple), fun (closure with frozen variable values), positive and negative bigint (tagged separately to avoid storing sign bit), float, export, refvalue, * refcounted binary*, heap binary, sub-binary, external pid, port, ref, match-state (internal object) and map.

Tuple

Tuple size on heap is its arity plus 1 Word header. Also, 1 Word to store each pointer to the tuple box.

Float

Float size is always 64 bit (1 or 2 words) + 1 Word header. Also, 1 Word to store each pointer to the float box.

Big Integer

Bigint size is ceil(log2^64(Number)) Words + 1 Word header. Thus, a less than 64bit integer will take 1 word, then 65-127bit will take 2 words and so on. On 32-bit architectures, of course, the Word size is 32 bit and all size calculations are 32-bit based. Also, +1 Word to store each pointer to the bigint box.

Last modified: 10 June 2024