WebAssembly 有一个WebAssembly.Memory
对象,而二进制文件有一个内存部分。通过这些,开发人员提供了关于最小和最大内存使用的有根据的猜测,然后 VM 至少分配最小值(或失败)。然后,开发人员可以在运行时询问更多grow_memory
像 Emscripten 这样的工具将在幕后使用malloc
(它有点类似于sbrk
)。
对于 asm.js,很难知道ArrayBuffer
将如何使用它,并且在某些 32 位平台上,您经常会遇到进程碎片,这使得很难在进程的虚拟内存中分配足够的连续空间(ArrayBuffer
必须是连续的)在浏览器进程的虚拟地址空间中,否则你会有一个巨大的性能命中)。您会尝试分配 256MiB,有时会出现硬故障。如果浏览器不是多进程的,这将变得非常困难,因为所有其他选项卡都在竞争 32 位虚拟地址空间。几年前浏览器有点傻,它们变得更好了,但是 32 位并没有什么好转的。
WebAssembly 由WebAssembly.Memory
一种特殊类型的ArrayBuffer
. 这意味着 WebAssembly 实现可以很聪明ArrayBuffer
。在 32 位上没有什么可做的:如果你用完了连续的地址空间,那么 VM 就无能为力了。但在 64 位平台上,有大量的地址空间。浏览器实现可以选择阻止您创建太多WebAssembly.Memory
实例(分配虚拟内存几乎是免费的,但并不完全),但您应该能够获得一些 4GiB 分配。请注意,浏览器只会虚拟分配该空间,并为您说需要的最少页面提交物理地址。之后它只会在您使用时进行物理分配grow_memory
. 这可能会失败(物理内存与 RAM 的数量一样丰富,给予或占用交换空间),但它更可预测。
假设允许碎片,实现可以在 32 位平台上使用类似的技巧(过度提交但保持PROT_NONE
而不是物理分配),但这取决于实现以及它认为这如何影响 ASLR。实际上,当没有太多可去的地方,但实际上和物理上,很难找到记忆。
WebAssembly 当前被指定为 ILP32 进程:指针为 32 位。因此,您被硬限制为 4GiB。我们将来可能会添加wasm64。