4.4 KiB
Memory usage estimation for a module
This document aims to provide information useful to make a rough estimation of necessary memory to execute a WASM module.
Instead of trying to cover every possible configurations, the following configuration is assumed in this document:
- Module is built with
wasi-sdk - Module is loaded with
wasm_runtime_load - AOT is used
- WASI is used
- libc heap is used
- app heap is not used
- The pthread implementation in
wasi-libc, which is based onwasi-threads(WASM_ENABLE_LIB_WASI_THREADS) might be used - The another pthread implementation (
WASM_ENABLE_LIB_PTHREAD) is not used
Module
The memory to store the module binary is allocated by the embedder and
passed to wasm_runtime_load.
While WAMR owns the buffer, WAMR might make in-place modifications to
its contents.
Loaded module and its instances
Many of data structures for module and instances are allocated from
the global heap. (aka. wasm_runtime_malloc)
AOT code section
Memory to load AOT machine code section.
Because this memory needs to be executable, depending on platforms,
it's allocated from a separate allocator.
For example, mmap and mprotect are used on POSIX-like platforms.
Linear memory
A WASM linear memory is either shared or non-shared.
A WASM linear memory has min and max sizes.
(They correspond to wasm-ld's --init-memory and --max-memory options.)
They are in the number of WASM pages, each of which is of 65536 bytes.
The max is optional for non-shared memory. When omitted, it effectivily
means unlimited.
If OS_ENABLE_HW_BOUND_CHECK is enabled, the memory is allocated via
os_mmap and os_mem_commit/os_mprotect.
Otherwise, it's allocated from the global heap.
If the memory is shared and OS_ENABLE_HW_BOUND_CHECK is not enabled,
the max size of memory is allocated on instantiation.
Otherwise, the min size of memory is allocated on instantiation.
It can later grow up to the max size via the memory.grow instruction.
Libc heap
The libc heap is the last (highest address) part of linear memory,
which might be dynamically grown with memory.grow instruction, when
necessary to serve memory allocations within the module.
App heap
Not used for the above mentioned configuration.
You can safely disable the app heap creation by specifying 0 for
the heap_size argument of wasm_runtime_instantiate.
(It's automatically disabled if malloc/free are exported from the module.)
WASM stack
Operand stack is not used for AOT.
However, a small amount of WASM stack is used for call frames when
certain features are enabled.
(WASM_ENABLE_DUMP_CALL_STACK or WASM_ENABLE_PERF_PROFILING)
It's allocated from the global heap.
You can specify its size with the stack_size argument of
wasm_runtime_instantiate and wasm_runtime_create_exec_env.
(1 is the minimum because 0 means the default.)
AUX stack (aka. C shadow stack)
For the main thread, it's a part of the linear memory,
between __data_end and __heap_base symbols.
You can control the size of this stack with wasm-ld's
-z stack-size option.
For threads created by pthread_create, libc allocates the stack for
them dynamically from the libc heap.
The size of this stack is inherited from the main thread's one
unless overwritten with pthread_attr_setstacksize etc.
WAMR tries to detect overflow/underflow when updating the stack pointer
global. For threads created by pthread_create, the detection mechanism
is disabled as of writing this.
Native stack
The stack of the host environment thread which runs WAMR.
For threads created by pthread_create, WAMR automatically creates
host threads to run those WASM threads. The stack size of these host
threads are controlled by a build-time configuration.
(APP_THREAD_STACK_SIZE_DEFAULT)
In some configurations, runtime overflow can be detected using hardware traps.
(OS_ENABLE_HW_BOUND_CHECK)
In some configurations, explicit overflow detection logic can be emitted
into AOT modules themselves. (cf. os_thread_get_stack_boundary,
check_stack_boundary, wamrc --stack-bounds-checks=1/0)
Memory profiling
You can collect and dump detailed information about memory usage
by actually running a module with the WASM_ENABLE_MEMORY_PROFILING
build-time option.