我编写了一些锈蚀代码并用wasm-pack编译了它。我注意到生成的free()文件中的这些.d.ts方法:
export class PdfDoc {
free(): void;
...
}PdfDoc拥有大量内存,最高可达1GB,因此当javascript代码完成时,所有内存都被正确释放以供重用是很重要的。
问题:
free()方法?我搜索了"wasm-pack免费方法“,但是这些搜索词的组合并没有发现任何有用的东西。
发布于 2022-10-22 08:51:04
我想知道同样的事情:在使用wasm时,是否需要仔细地将每个new MyStruct()与对free()的调用配对?
什么时候应该调用这些空闲()方法?
在失去对JS对象包装实例的最后引用之前调用free(),如果使用对象完成,则调用更早的引用。
我需要显式地调用它们还是会自动调用它们?
目前,当JS对象包装器超出范围(但是s.a )时,WASM分配的内存将不会释放。(下文引用较少)。
如果我从来不给他们打电话怎么办?
WASM内存丢失了,如果没有指针,您将无法恢复它。对于固定或有限数量较小的结构来说,这可能不是问题,卸载页面时会释放整个WASM内存。
更详细的是:
查看创建的绑定,我们发现在构造函数中分配的内存不会被跟踪到其他地方,如果我们忘记了返回的实例(一个JS包装器对象,它将原始指针存储为ptr),那么它实际上就丢失了。
对弱引用的支持中的wasm-bindgen指南也暗示了这一点,其中提到TC39弱引用目前(2022年末)不支持/实现:
如果没有弱引用,您的JS集成可能容易受到锈蚀中内存泄漏的影响,例如:您可能忘记对JS对象调用.free(),留下分配的Rust内存。
wasm-bindgen示例WebAudio演示了在重复创建超出作用域的对象时如何使用free()来防止内存泄漏。最多只剩下一个(活动的)对象,这主要反映了您的用例:当对象不再需要时,在对象超出作用域之前调用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
}
}在Rust中,这是很容易使用和安全的代码,但是如果简单地从JS中使用,这里会泄漏内存,比如
console.log(`Current width is ${myThing.bounds.width} px`);开发时,您可能需要查看WASM内存。
console.log(`WASM memory usage is ${wasm.memory.buffer.byteLength} bytes`);https://stackoverflow.com/questions/73655844
复制相似问题