emscripten-core / emscripten-core/emscripten

emscripten objects/modules deletion/unloading

Open
#18,080 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Hello guys! Can you help me to check how can I track the lifetime of an object loaded in an `emscripten app` (TS + C++)?

Context: I want to implement a feature where I am trying to reload the app in the same Worker (without killing it). I actually need to destroy all objects inside the this worker. Destroy here can mean to make sure the object is Garbage Collected OR to manually destroys it (if needed - check `3`). Basically, I want to implement a `shutdown` mechanism which is similar with releasing all memory (TS + C++) and check I don't have leaks, like in the C++ world :D.

I found few types of objects in my project:

1. “standard” objects: objects created in TS (not C++ related - e.g. no bindings at all) are automatically freed by the GC. This also includes objects created and kept inside C++ using `emscpriten::val`. Basically `1` is handled by GC.

2. “shared types/objects” + stack allocation: object allocated in C++ on stack and returned to JS. They are automatically GC-ed (be like standard JS objects).

3. “shared types/objects” + heap allocation: e.g. type defined in C++, bind into a TS/JS interface. If in TS I end up using dynamic allocation (a.k.a. `new $interface_from_cpp()`), I must manually call `$object.delete()` in JS (check [docs](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html?highlight=memory): `It is strongly recommended that JavaScript code explicitly deletes any C++ object handles it has received. The delete() JavaScript method is provided to manually signal that a C++ object is no longer needed and can be deleted. Both C++ objects constructed from the JavaScript side as well as those returned from C++ methods must be explicitly deleted.`).

4. `EmscriptenModule`-like objects, which from my understanding, will be actually used to load the WASM file intro the browser (?). The lifetime of the `EmscriptenModule` object is the same as for WASM? (e.g. [by releasing all references to the module, will automatically unload the WASM](https://stackoverflow.com/a/56035811/6068071)?)

5. `bindings `- by actually using `EMSCRIPTEN_BINDINGS` it seems the runtime creates some global variables (emscripten internal stuff) . They seem to be released when calling `atexit` ([ if this exists (e.g. in a C++ main() -based problem) ](https://emscripten.org/docs/getting_started/FAQ.html?highlight=atexit#what-does-exiting-the-runtime-mean-why-don-t-atexit-s-run) : `That means that when main() exits, we don’t flush the stdio streams, or call the destructors of global C++ objects, or call atexit callbacks`). In my case, I don't have a `main()` function. I am running in a [request frame animation](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) based loop. How can I trigger destroying the actual runtime / bindings?

Q1: Do you know about any object which is not in {1, 2, 3, 4, 5}?

Q2: If 4 is true (destroy module => unload WASM), how can I test this? I don’t really know how to test that works (e.g. check WASM is not present anymore? OR that my operation is a NOP - the module object was GC-ed? and the WASM is still present? ). I didn’t get my answer with Chrome Dev Tools (Memory tab) - maybe I am missing something.

Q3: How do I solve 5? :D Unload WASM => destroy bindings?

Q4: I know about using [Emscripten Sanitizer](https://emscripten.org/docs/debugging/Sanitizers.html) , this is how I discovered that I have memory leaks for bindings. Do you recommend other tools?

Please let me know if I can give you any other information. Thanks!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.