我希望通过定期记录WASM堆的已用部分的大小来检测内存泄漏.最简单的方法是什么?
我以为《Rust and WebAssembly》一书对此有一些建议,但我找不到.
我希望通过定期记录WASM堆的已用部分的大小来检测内存泄漏.最简单的方法是什么?
我以为《Rust and WebAssembly》一书对此有一些建议,但我找不到.
正如注释中所解释的,您可以通过JavaScript获得WASM(WebAssembly.Memory.prototype.buffer.byteLength
)中的总内存使用量.这永远不会缩小,但如果它不断增长,那么你可能有泄漏.你可以通过wasm_bindgen::memory()
获得WebAssembly.Memory
实例,其余的可以通过wasm_bindgen
完成:
fn get_current_allocated_bytes() -> u64 {
#[wasm_bindgen]
extern "C" {
type Memory;
#[wasm_bindgen(method, getter)]
fn buffer(this: &Memory) -> MaybeSharedArrayBuffer;
type MaybeSharedArrayBuffer;
#[wasm_bindgen(method, getter = byteLength)]
fn byte_length(this: &MaybeSharedArrayBuffer) -> f64;
}
wasm_bindgen::memory()
.unchecked_into::<Memory>()
.buffer()
.byte_length() as u64
}
如果你想要一个更高性能的实现(这会相当慢),或者如果你想要一个更精确的度量(如前所述,这不会计算释放),你可以实现一个全局分配器:
use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicIsize, Ordering};
struct CountingAllocator<A> {
inner: A,
allocated_now: AtomicIsize,
}
impl<A> CountingAllocator<A> {
const fn new(inner: A) -> Self {
Self {
inner,
allocated_now: AtomicIsize::new(0),
}
}
fn allocated_now(&self) -> usize {
self.allocated_now
.load(Ordering::Relaxed)
.try_into()
.unwrap_or(0)
}
}
unsafe impl<A: GlobalAlloc> GlobalAlloc for CountingAllocator<A> {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
self.allocated_now
.fetch_add(layout.size() as isize, Ordering::Relaxed);
self.inner.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
self.allocated_now
.fetch_sub(layout.size() as isize, Ordering::Relaxed);
self.inner.dealloc(ptr, layout);
}
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
self.allocated_now
.fetch_add(layout.size() as isize, Ordering::Relaxed);
self.inner.alloc_zeroed(layout)
}
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
self.allocated_now.fetch_add(
new_size as isize - layout.size() as isize,
Ordering::Relaxed,
);
self.inner.realloc(ptr, layout, new_size)
}
}
#[global_allocator]
static ALLOCATOR: CountingAllocator<System> = CountingAllocator::new(System);
然后调用ALLOCATOR.allocated_now()
以检索当前分配的字节的确切数目.