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