我有一个用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
我如何成功释放此内存?
答案 0 :(得分:10)
WebAssembly does not offer any instructions to deallocate memory,只能增加分配的大小。实际上,这意味着WebAssembly应用程序的峰值内存使用量也是永久内存使用量。
对于给定的问题,可能可以调整算法以减少内存的峰值量。
我没有测试的知识或能力,但是一个即用的想法是尝试让多个WebAssembly运行时彼此不同。您可以在一个内存中消耗很多内存来计算相对较小的结果,在WASM运行时之外将该结果序列化,然后将其丢弃并启动一个新的内存。这可能仅在某些特定问题域中有用。
将来,可能会重新将内存大小调整添加到WebAssembly。在MVP发布之前已将其明确删除:
在执行MVP之后,我们将转移到分歧且无法进行多填充的事物,并且在该时间点添加内存大小调整更有意义。
感谢alexcrichton和steveklabnik在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});