首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >何时应该调用由wasm-pack生成的空闲()方法?

何时应该调用由wasm-pack生成的空闲()方法?
EN

Stack Overflow用户
提问于 2022-09-08 23:18:43
回答 1查看 95关注 0票数 0

我编写了一些锈蚀代码并用wasm-pack编译了它。我注意到生成的free()文件中的这些.d.ts方法:

代码语言:javascript
复制
export class PdfDoc {
  free(): void;
  ...
}

PdfDoc拥有大量内存,最高可达1GB,因此当javascript代码完成时,所有内存都被正确释放以供重用是很重要的。

问题:

  • 什么时候应该调用这些free()方法?
  • 我需要显式地调用它们还是会自动调用它们?
  • 如果我从来不给他们打电话怎么办?

我搜索了"wasm-pack免费方法“,但是这些搜索词的组合并没有发现任何有用的东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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()来清理对象。

作为对仔细内存管理的补充:

在使用复制类型时,可能会有一个设计陷阱需要注意,请考虑:

代码语言:javascript
复制
#[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中使用,这里会泄漏内存,比如

代码语言:javascript
复制
console.log(`Current width is ${myThing.bounds.width} px`);

开发时,您可能需要查看WASM内存。

代码语言:javascript
复制
console.log(`WASM memory usage is ${wasm.memory.buffer.byteLength} bytes`);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73655844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档