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

Ada*_*m R 14 rust webassembly

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

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>,
}
Run Code Online (Sandbox Code Playgroud)

我尝试以下方法删除数据并释放内存,并从中删除数据,HashMap并且不会报告错误:

#[wasm_bindgen]
pub fn remove_data(id: u32) {
    match ID_TO_DATA.lock().unwrap().remove(&id) {
        Some(data) => {
            std::mem::drop(data);
        }
        None => {}
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,浏览器选项卡使用的内存不会丢失(使用Chrome 67).我使用Windows的任务管理器,并观察相关进程/选项卡的内存增长到近2GB,然后在我的程序删除所有条目后,我等了一会儿,内存仍然接近2GB.

我也试过以下,但得到了这个错误: RuntimeError: memory access out of bounds

#[wasm_bindgen]
pub fn remove_data(id: u32) {
    match ID_TO_DATA.lock().unwrap().remove(&id) {
        Some(mut data) => {
            unsafe {
                std::ptr::drop_in_place(&mut data);
            }
        }
        None => {}
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能成功释放这段记忆?

She*_*ter 12

WebAssembly不提供释放内存的任何指令,只能增加分配的大小.实际上,这意味着WebAssembly应用程序的峰值内存使用量也是永久内存使用量.

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

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


将来,可以将内存大小调整重新添加到WebAssembly.它在MVP发布之前被明确删除:

在MVP之后,我们正在转向分散且无法填充的事物,并且内存调整大小在那个时间点添加更有意义.

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