[译]WebAssembly 中的 Memory

原文链接:https://fanmingfei.com/posts/...

这是系列文章第二篇:


WebAssembly中的内存与JavaScript中的内存有所不同。使用WebAssembly,您可以直接访问原始字节码...这可能令人担忧。但是,它的确比你想象中的要安全。

什么是 memory 对象?

当 WebAssembly 模块被实例化时,它需要一个 memory 对象。你可以创建一个新的WebAssembly.Memory并传递该对象。如果没有创建 memory 对象,在模块实例化的时候将会自动创建,并且传递给实例。

JS引擎创建一个ArrayBuffer(我在另一篇文章中解释)来做这件事情。ArrayBuffer 是 JS 引用的 JavaScript 对象。JS 为你分配内存。你告诉它需要多少内存,它会创建一个对应大小的ArrayBuffer。

React.js requesting a new memory object and JS engine creating one

数组的索引可以视为内存地址。如果你需要增加它的内存,你可以使用 grow 方法让数组变大。

ArrayBuffer 做了两件事情,一件是做 WebAssembly 的内存,另外一件是做 JavaScript 的对象。

  1. 它使 JS 和 WebAssembly 之间传递内容更方便。

  2. 使内存管理更安全。

JS 和 WebAssembly 之间传值

因为 ArrayBuffer 是一个 JavaScript 对象,这意味着 JavaScript 也可以获取到这个 memory 中的字节。所以通过这种方式, WebAssembly 和 JavaScript 可以共享内存,并且相互传值。

使用数组索引来访问每个字节,而不是使用内存地址。

比如,WebAssembly 想将一个字符串写入内存。它需要将字符串转换成字节码。

WebAssembly robot putting string "Hello" through decoder ring

然后把这些字节码放进数组。

WebAssembly robot putting bytes into memory

然后将字符串所在的内存位置的第一个位置,也就是数组的某个索引,传递给 JavaScript。JavaScript 可以根据索引从 ArrayBuffer 中拿到字符串

WebAssembly robot returning index of first byte in string

现在,很多人并不知道如何在 JavaScript 中使用字节码。你需要将字节码转换为有用的内容,比如说字符串。

在一些浏览器中,你可以使用TextDecoderTextEncoderAPI来处理。或者你可以在你的js文件里添加一些帮助函数。比如,Emscripten就可以帮你添加编码和解码的方法。

JS engine pulling out bytes, and React.js decoding them

所以,WebAssembly memory 最好的地方就是它是一个 JS 对象。WebAssembly 和 JavaScript 可以直接使用 memory 互相传值。

让 memory 存取更安全

另外一个好处是,WebAssembly memory 只是一个 JavaScript 对象:安全。通过防止浏览器级内存泄漏并提供内存隔离,使事情变得更安全。

内存泄漏

正如我在内存管理的文章中提到的,当你管理自己的内存时,你可能会忘记清除它。这可能导致系统内存不足。

如果 WebAssembly 模块实例直接访问内存,并且如果在超出范围之前忘记清除该内存,那么浏览器可能会泄漏内存。

因为内存对象只是一个JavaScript对象,所以它本身就被垃圾回收器跟踪(尽管它的内容不会垃圾回收)。

也就是说,WebAssembly 实例被移除以后,所有的内存数组将会被回收。

Garbage collector cleaning up memory object

内存隔离

当人们听到WebAssembly让你直接访问内存时,他们可能有点紧张。他们认为,一个恶意的 WebAssembly 模块可能会进入并在内存中干坏事,这是绝对不允许的。但事实并非如此。

ArrayBuffer 提供了边界。WebAssembly 模块可以直接管理的内存是受限制的。

Red arrows pointing to the boundaries of the memory object

它可以直接管理该数组内部的字节,但它看不到任何超出此数组范围的内容。

例如,内存中的任何其它 JS 对象,如 window 对象,WebAssembly无法访问。这对安全性非常重要。

每当 WebAssembly 中有操作内存时,引擎会进行数组限制检查,以确保该地址位于 WebAssembly 实例的内存中。

如果代码尝试访问超出范围的地址,引擎将抛出异常。这保护了其它的内存。

WebAssembly trying to store out of bounds and being rejected

所以这就是 memory 相关的内容。在下一篇文章中,我们将看研究一些关于安全性的其它类型的 import 数据:table import

About

Lin Clark

Lin 是Mozilla Developer Relations团队的工程师。她使用 JavaScript、WebAssembly、Rust 和 Servo,也画一些漫画。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在SimulinkMemory模块是一个用于存储和检索数据的关键模块。它与MATLAB工作空间的变量类似,可以使得模型的不同部分之间传递和共享数据。 Memory模块有三种基本类型:单端口、双端口和存储块。 单端口Memory模块只有一个输入端口和一个输出端口。当接收到输入信号时,该模块会将输入信号的值储存在一个内部缓冲区,并将该值通过输出端口传递。当下一个输入信号到达时,该模块将更新缓冲区的值,并将新的值传递给输出端口。 双端口Memory模块有两个输入端口和一个输出端口。其一个输入端口用于接收输入信号,另一个输入端口用于接收控制信号。当控制信号为高时,模块将输入信号的值储存在内部缓冲区,并将该值通过输出端口传递。当控制信号为低时,该模块将缓冲区的值保持不变,并继续将该值传递给输出端口。 存储块Memory模块允许用户创建一个由多个内存单元组成的存储块。每个内存单元都有一个地址,可以用于存储和检索数据。存储块Memory模块通常与其他数学运算模块(如Add或Multiply)一起使用,以实现复杂的计算。 使用Memory模块可以方便地在Simulink模型存储和共享数据,提高模型的可重用性和可维护性。通过使用Memory模块,我们可以在不同的模块之间传递数据,实现模型的各个部分之间的数据交换和通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值