WebAssembly中最大内存限制的含义是什么?

时间:2019-05-01 10:10:59

标签: memory limit webassembly jwebassembly

当我在WebAssembly中声明memory section时,我必须设置初始大小,并且可以设置可选的最大大小。

如果将最大值设置为与初始值相同,是否有任何优势?此值对WebAssembly运行时有什么影响?

背景:我写了Java to WebAssembly compiler,并想使用即将到来的GC功能处理我的数据。我不需要增加内存。我只会将其用于常量值。

1 个答案:

答案 0 :(得分:2)

分配大内存(尤其是千兆字节时)可能会失败。无法分配初始内存是一个致命错误,而以后未能增长内存则不是。因此,以较小且安全的初始大小开始是个好主意。

WebAssembly社区已经提供了很好的文档:

我将在此处总结有关WebAssembly内存工作方式的信息。

为什么我们需要可选的最大尺寸

基础WebAssembly MemoryJS ArrayBuffer对象。 ArrayBuffer不是动态数组,这意味着无法调整大小。但是,Wasm内存是一个特殊的ArrayBuffer,可以通过Memory.grow()调用来调整大小,它对应于Wasm中的grow_memory指令。调整ArrayBuffer的大小仍然需要花费大量成本-与realloc()相同,后者分配了具有新大小的新缓冲区,然后释放了旧缓冲区。您可以通过分配大的初始内存来避免重新分配缓冲区的开销,但这会导致另一个问题,即操作可能失败并且失败,这意味着Wasm引擎无法加载Wasm二进制文件。

可选的最大尺寸解决了这些问题。定义最大大小后,Wasm内存会尝试预先分配缓冲区的最大大小。通过预分配缓冲区,您可以稍后重新调整缓冲区大小,而无需进行昂贵的realloc()操作。即使预分配操作失败也可以-您可以稍后在需要时尝试重新分配。

WebAssembly内存大小调整方案

  • grow_memory,而未设置最大大小:Wasm引擎尝试重新分配整个缓冲区,这非常昂贵,并且增加了失败的可能性。
  • 分配大的初始内存:它可能会失败,并且失败是一个致命错误。
  • grow_memory,具有最大大小:引擎将立即使用预分配的缓冲区。即使增长失败,也不是致命的错误。
  • 设置初始大小==最大大小:您将不会从其中任何一个中受益。它可能会遇到致命错误,并且以后也无法调整大小。