本文介绍了如何释放由 WebAssembly 中公开的 Rust 代码分配的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a web application written in Rust and wasm-bindgen that needs to store state. The state is stored like this:

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中删除并且没有报告错误:

I attempted the following to remove the data and free the memory, and the data is removed from the HashMap and no errors are reported:

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

然而,浏览器标签使用的内存永远不会下降(使用 Chrome 67).我使用 Windows 的任务管理器,看到相关进程/选项卡的内存增长到近 2GB,然后在我的程序删除所有条目后,我等了一分钟,内存仍然接近 2GB.

However, the memory used by the browser tab never drops (using Chrome 67). I used Windows' Task Manager and watched the memory grow to almost 2GB for the relevant process/tab, and then after my program removed all the entries, I waited a minute and the memory was still at almost 2GB.

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

I also tried the following, but got this error: 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 => {}
    }
}

我怎样才能成功释放这个内存?

How can I successfully free this memory?

推荐答案

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

WebAssembly does not offer any instructions to deallocate memory, there is only the ability to increase the allocated size. Practically speaking, this means that the peak memory usage of your WebAssembly application is also the permanent memory usage.

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

For a given problem, it may be possible to tweak your algorithm to reduce the peak amount of memory.

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

I don't have the knowledge or ability to test this, but one out-of-the-box idea would be to try and have multiple WebAssembly runtimes distinct from each other. You could chew up a lot of memory in one to compute a relatively small result, serialize that result outside of the WASM runtime, then throw it away and spin up a new one. This is likely only to be useful in certain specific problem domains.

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

In the future, memory resizing may be re-added to WebAssembly. It was explicitly removed before the MVP release:

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

08-29 07:37