当我在WebAssembly中声明memory section时,我必须设置初始大小,并且可以设置可选的最大大小。
如果将最大值设置为与初始值相同,是否有任何优势?此值对WebAssembly运行时有什么影响?
背景:我写了Java to WebAssembly compiler,并想使用即将到来的GC功能处理我的数据。我不需要增加内存。我只会将其用于常量值。
答案 0 :(得分:2)
分配大内存(尤其是千兆字节时)可能会失败。无法分配初始内存是一个致命错误,而以后未能增长内存则不是。因此,以较小且安全的初始大小开始是个好主意。
WebAssembly社区已经提供了很好的文档:
我将在此处总结有关WebAssembly内存工作方式的信息。
基础WebAssembly Memory是JS ArrayBuffer对象。 ArrayBuffer不是动态数组,这意味着无法调整大小。但是,Wasm内存是一个特殊的ArrayBuffer,可以通过Memory.grow()调用来调整大小,它对应于Wasm中的grow_memory
指令。调整ArrayBuffer的大小仍然需要花费大量成本-与realloc()
相同,后者分配了具有新大小的新缓冲区,然后释放了旧缓冲区。您可以通过分配大的初始内存来避免重新分配缓冲区的开销,但这会导致另一个问题,即操作可能失败并且失败,这意味着Wasm引擎无法加载Wasm二进制文件。
可选的最大尺寸解决了这些问题。定义最大大小后,Wasm内存会尝试预先分配缓冲区的最大大小。通过预分配缓冲区,您可以稍后重新调整缓冲区大小,而无需进行昂贵的realloc()
操作。即使预分配操作失败也可以-您可以稍后在需要时尝试重新分配。
grow_memory
,而未设置最大大小:Wasm引擎尝试重新分配整个缓冲区,这非常昂贵,并且增加了失败的可能性。grow_memory
,具有最大大小:引擎将立即使用预分配的缓冲区。即使增长失败,也不是致命的错误。