webassembly程序的内存分配限制政策是什么?
当前(硬)javascript引擎内存限制是否会被继承? 例如。是否可以编写需要超过几百兆内存的真实应用程序?
当前关于javascript内存分配的浏览器策略对浏览器中实际可行的内容构成了严格限制。 emscripten / asm.js和jit编译速度不再是问题,但内存限制使得在浏览器中构建任何严肃的应用程序变得困难或不可能。
参见例如http://www.meshlabjs.net,即MeshLab网格处理系统的浏览器版本。关于桌面应用程序,主要限制是,在基于javascript的版本中,不能加载大型3D模型以用于由浏览器的js引擎施加的分配的固有限制。
答案 0 :(得分:9)
WebAssembly有一个WebAssembly.Memory
对象,二进制文件有一个memory section。通过这些,开发人员提供有关最小和最大内存使用量的有根据的猜测,然后VM分配至少最小(或失败)。然后,开发人员可以在运行时通过grow_memory
更多地询问Emscripten之类的工具将在malloc
的引擎下使用(它有点类似于sbrk
)。
对于asm.js,很难知道ArrayBuffer
将如何使用,在某些32位平台上,您经常遇到进程碎片,这使得在进程中分配足够的连续空间变得困难#39;虚拟内存(ArrayBuffer
必须在浏览器进程的虚拟地址空间中是连续的,否则您将拥有巨大的性能。您尝试分配256MiB,有时难以失败。如果浏览器不是多进程的话,这非常困难,因为所有其他选项卡都在竞争32位的虚拟地址空间。浏览器were a bit silly a few years ago, they got better,但32位还不错。
WebAssembly由WebAssembly.Memory
支持,ArrayBuffer
是一种特殊类型的ArrayBuffer
。这意味着WebAssembly实现可以很聪明地WebAssembly.Memory
。在32位上没有什么可做的:如果你用完了连续的地址空间,那么VM就不会做太多。但在64位平台上,有足够的地址空间。浏览器实现可以选择阻止您创建太多grow_memory
个实例(分配虚拟内存几乎免费,但不完全),但您应该能够获得一些4GiB分配。请注意,浏览器只会虚拟地分配该空间,并提交您所需的最少页数的物理地址。之后,它只会在您使用PROT_NONE
时进行物理分配。这可能会失败(物理内存与RAM的数量一样多,给予或占用交换空间),但它的很多更容易预测。
实现可以在32位平台上提取类似技巧(过度提交但保留{{1}}而不是物理分配),假设碎片允许,但这取决于实现及其思考方式这会影响ASLR。实际上,如果没有多少东西可以找到记忆,但是在虚拟和物理上都很难找到记忆。
WebAssembly当前被指定为ILP32进程:指针是32位。因此,你很难受4GiB的限制。我们将来可能会添加wasm64。
答案 1 :(得分:1)
相关提案(see their current stages here):
此建议增加了在单个Wasm模块中使用多个内存的能力。在当前版本的Wasm中,一个应用程序已经可以创建多个内存,但是只能将其拆分为多个模块。单个模块或功能不能同时引用多个存储器。因此,不可能例如高效地将数据从一个内存传输到另一个内存,因为这必然涉及将每个函数的每个值调用到不同的模块中。
https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md
本页描述了支持大于2 ^ 32位的线性存储器的建议。它没有提供任何新指令,而是扩展了现有指令以允许64位索引。
WebAssembly线性存储对象的大小以页为单位。每页为65536(2 ^ 16)字节。在WebAssembly版本1中,线性内存最多可以有65536页,总共2 ^ 32字节(4吉字节)。除了该页数限制,当前所有内存指令都将i32类型用作内存索引。这意味着它们最多也可以寻址2 ^ 32字节。
https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md
答案 2 :(得分:0)
我总结了一下上面的答案,评论以及更多的谷歌搜索;有两个问题阻止使用WebAssembly来处理需要大量内存的项目:
希望这两个问题都能解决。我希望浏览器能够以明确的方式暴露这些限制;就像通知页面请求使用相机一样,您应该只是通知用户页面需要大量内存并阻止它直到您回答。