New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebIDL-wrapped C++ objects are never garbage collected #19438
Comments
The "Reclaim" text when clicked should delete the Module and re-create it. This messes up the memoryprofiler which then flickers between the old modules, which I'm guessing it is keeping alive. I also tried this reclaim without the memoryprofiler option in use. Using the heap snapshot feature of the memory tab of chrome devtools, it is clear that the MyVector instances remain, even after deleting the Module. This is easier to see if the size of MyVector is reduced and more of them are created each time I notice that the generated |
Some links:
Possibly EmBind has better handling of this than WebIDL? Also - https://discourse.threejs.org/t/ammo-js-with-three-js/12530/82 It is looking like this is a known issue and the documentation for WebIDL is just very wrong. It is also very inconvenient to have to explicitly destroy objects. This is not maintainable as the function inevitably grown new conditions and exit conditions:
|
Given how long this has been an issue for, I'm guessing it is not trivial to resolve. I'm experimenting with ways to work around this. Most of my types that are created frequently are value types, so something like
can be used like
but no matter how I name things, someone will do this and not understand why it fails:
Also, It is normal to need to have two MyVectors alive at once, so the singleton is a non-runner. So, this is also not a good solution. Another idea is to create a utility to scope the use of an instance, which at least means we can use two instances at once:
It could also potentially be improved by implementing it with a freelist etc. The big downsides are
This all seems to be a case of "Choose your bad". What do others do about this? @juj @kripken this is stuff you hit in ammo/unity surely? |
I think those docs are confusing, yeah. A PR to improve them would be welcome. What I think is the truth is that the JS wrapper objects are automatically GC'd by the JS VM, like any JS object. But the allocations in the C++ heap must be manually freed. It is possible to improve this using JS finalizers (which would destroy the C++ object automatically), but I'm not sure how much work that would be. Embind has some support for that. |
Please include the following in your bug report:
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.39 (36f8718)
clang version 17.0.0 (https://github.com/llvm/llvm-project c672c3fe05adbb590abc99da39143b55ad510538)
Target: wasm32-unknown-emscripten
Thread model: posix
Repro
This shell script generates bindings using WebIDL, starts a simple http server and creates a webpage to open:
Open
http://localhost:8000/?trackbytes=1000&trackcount=100
in the browser.After a few seconds of operation, the tab crashes in Chrome and FF due to OOM.
From this documentation:
https://emscripten.org/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.html#using-c-classes-in-javascript
This test case shows that that is not the case. The wrapped objects are never garbage collected. The wrapped type does not have a destructor which needs to be invoked.
The documentation also notes:
This is confusing and contradictory.
If the radio button is selected to destroy objects after creating them, then
destroy
is called and memory stops growing. This is not a reasonable workaround as the code becomes unmaintainable very quickly.If this is not fixed, at least the documentation should be updated to indicate that all wrapped objects must be explicitly destroyed.
The text was updated successfully, but these errors were encountered: