Jef*_*nie 4 rust wasm-bindgen wasm-pack
我编写了一些 Rust 代码并使用 wasm-pack 对其进行了编译。free()我在生成的 .d.ts 文件中注意到这些方法:
export class PdfDoc {
free(): void;
...
}
Run Code Online (Sandbox Code Playgroud)
PdfDoc拥有大量内存,高达 1GB,因此当 javascript 代码使用完这些内存时,正确释放所有内存以供重用非常重要。
问题:
free()方法?我搜索了“wasm-pack free method”,但这些搜索词组合没有找到任何有用的东西。
我想知道同样的事情:使用 wasm-bindgen 时是否需要仔细地将每个new MyStruct()函数与调用配对?free()
我什么时候应该调用这些 free() 方法?
在丢失对 JS 对象包装器实例的最后一个引用之前调用free(),或者如果您使用完该对象,则更早调用。
我需要显式调用它们还是会自动调用它们?
目前,当 JS 对象包装器超出范围时,WASM 分配的内存将不会释放(但下面是弱引用)。
如果我从不打电话给他们会怎样?
WASM 内存丢失,如果没有指针,您将无法恢复它。对于固定或有限数量的较小尺寸的结构来说,这可能不是问题,整个 WASM 内存在卸载页面时被释放。
更详细地说:
查看创建的绑定,我们发现在构造函数中分配的内存不会在其他地方被跟踪,并且如果我们忘记返回的实例(一个将原始指针存储为 的 JS 包装对象ptr),则会有效地丢失内存。
wasm-bindgen 指南还在弱引用支持中暗示了这一点 ,提到目前不支持/实现 TC39 弱引用(2022 年末):
如果没有弱引用,您的 JS 集成可能容易受到 Rust 中内存泄漏的影响,例如:您可能忘记在 JS 对象上调用 .free(),从而留下分配的 Rust 内存。
wasm-bindgen 指南示例WebAudiofree()显示了在重复创建超出范围的对象时防止内存泄漏的用法。最多只剩下一个(活动的)对象,这主要反映了您的用例:通过free()在不再需要对象时和超出范围之前调用来清理对象。
作为仔细内存管理的补充:
使用复制类型时可能需要注意一个设计问题,请考虑:
#[wasm_bindgen]
#[derive(Clone, Copy)]
pub struct Bounds {
width: usize,
height: usize,
}
#[wasm_bindgen]
impl Bounds {
// ...
#[wasm_bindgen(getter)]
pub fn width(&self) -> usize {
self.width
}
}
#[wasm_bindgen]
pub struct MyThing {
bounds: Bounds,
// ...
}
#[wasm_bindgen]
impl MyThing {
// ...
#[wasm_bindgen(getter)]
pub fn bounds(&self) -> Bounds {
self.bounds
}
}
Run Code Online (Sandbox Code Playgroud)
这是 Rust 中常见且安全的代码,但如果简单地从 JS 中使用,则会泄漏内存,例如
console.log(`Current width is ${myThing.bounds.width} px`);
Run Code Online (Sandbox Code Playgroud)
您可能想在开发时观察 WASM 内存,例如
console.log(`WASM memory usage is ${wasm.memory.buffer.byteLength} bytes`);
Run Code Online (Sandbox Code Playgroud)
正如从 v0.2.91 开始的评论中所指出的,“如果检测到支持,wasm-bindgen 确实会使用 TC39 弱引用提案。在撰写本文时,所有主要浏览器都支持它。” ( wasm-bindgen ) 即如果浏览器支持弱引用,WASM 分配的内存将自动释放。
| 归档时间: |
|
| 查看次数: |
757 次 |
| 最近记录: |