如何释放WebAssembly中公开的Rust代码分配的内存?

时间:2018-07-26 17:12:33

标签: rust webassembly

我有一个用Rust和wasm-bindgen编写的Web应用程序,需要存储状态。状态存储如下:

user.user.uid

我尝试了以下操作来删除数据并释放内存,然后从lazy_static! { static ref ID_TO_DATA: Mutex<HashMap<u32, Data>> = Mutex::new(HashMap::new()); } pub struct Data { pub coder_id: u16, pub bools: Vec<bool>, pub ints: Vec<i32>, pub strings: Vec<String>, } 中删除了数据,并且未报告任何错误:

HashMap

但是,浏览器选项卡使用的内存永不减少(使用Chrome 67)。我使用Windows的任务管理器,并查看相关进程/选项卡的内存增加到将近2GB,然后在程序删除所有条目之后,我等待了一分钟,内存仍然接近2GB。

我也尝试了以下操作,但出现此错误:#[wasm_bindgen] pub fn remove_data(id: u32) { match ID_TO_DATA.lock().unwrap().remove(&id) { Some(data) => { std::mem::drop(data); } None => {} } }

RuntimeError: memory access out of bounds

我如何成功释放此内存?

2 个答案:

答案 0 :(得分:10)

WebAssembly does not offer any instructions to deallocate memory,只能增加分配的大小。实际上,这意味着WebAssembly应用程序的峰值内存使用量也是永久内存使用量。

对于给定的问题,可能可以调整算法以减少内存的峰值量。

我没有测试的知识或能力,但是一个即用的想法是尝试让多个WebAssembly运行时彼此不同。您可以在一个内存中消耗很多内存来计算相对较小的结果,在WASM运行时之外将该结果序列化,然后将其丢弃并启动一个新的内存。这可能仅在某些特定问题域中有用。


将来,可能会重新将内存大小调整添加到WebAssembly。在MVP发布之前已将其明确删除:

  

在执行MVP之后,我们将转移到分歧且无法进行多填充的事物,并且在该时间点添加内存大小调整更有意义。

感谢alexcrichtonsteveklabnik在Rust Discord中回答了这个问题。

答案 1 :(得分:0)

我的访问者在我的网站上花费数小时而无需重新加载。

我的 wasm 程序每 5 分钟运行一次,每次运行 0.5 秒。它由一个同步 JS 函数调用,它期望在 wasm 完成后立即输出。在执行过程中,wasm 程序需要 700 MB 的 RAM。

我想在 wasm 程序不运行时释放这 700 MB。我应该释放哪个 JS 对象(删除对它的引用)?下次我的JS函数运行时,我想再次运行wasm程序(以同步方式)。

每次运行我的 JS 函数时,我都在考虑重新编译 WASM,但当前所有浏览器都是异步编译 WASM。还有什么我可以做的吗?

这些行什么都不做:

wasm.instance.exports.memory.buffer = new ArrayBuffer(10);
wasm.instance.exports.memory = new WebAssembly.Memory({initial:10});