When I declare a memory section in a WebAssembly then I have to set the initial size and I can set the optional maximum size.
Does it have any advantages if I set the maximum to the same value as the initial value? What are the implications of this value for WebAssembly runtime?
Background: I write a Java to WebAssembly compiler and want to use the coming GC feature for my data. I does not need to grow the memory. I would use it only for constant values.
Allocating a large memory (especially when it's gigabytes) may fail. Failed to allocate the initial memory is a fatal error, while failed to grow the memory later is not. So it is a good idea to start with a smaller and safe initial size.
The WebAssembly communities already provides pretty good documentations:
I will sum up the information on how WebAssembly memory works here.
Why we need the optional maximum size
The underlying WebAssembly Memory is a JS ArrayBuffer object. ArrayBuffer is not a dynamic array, meaning it cannot be resized. However, Wasm Memory is a special ArrayBuffer that can be resized by Memory.grow() call, which is correspondent to
grow_memoryinstruction in Wasm. Still, implementation of resizing ArrayBuffer costs a lot - It is the same asrealloc(), which allocate a new buffer with the new size then deallocate the old buffer. You may avoid the overhead of reallocating the buffer by allocating a large initial memory but it causes another problem that the operation may fail and failed to do so means the Wasm engine failed to load the Wasm binary.The optional maximum size solves those problems. When the maximum size is defined, the Wasm Memory tries to pre-allocate the maximum size of the buffer. By pre-allocating the buffer you can resize the buffer later without an expensive
realloc()operation. It is okay even if the pre-allocating operation failed - you can try reallocte later when you need.WebAssembly Memory Resizing Scenarios
grow_memorywithout setting the maximum size: The Wasm engine tries to reallocate the whole buffer, which is very expensive and increases possibilities to fail.grow_memorywith the maximum size: The engine will use pre-allocated buffer instantly. Even if it failed to grow it is not a fatal error.