r-wasm / webr

The statistical language R compiled to WebAssembly via Emscripten, for use in web browsers and Node.
https://docs.r-wasm.org/webr/latest/
Other
848 stars 67 forks source link

The webR `Shelter` mechanism sometimes leaks memory to the Global Shelter #423

Open christianp opened 4 months ago

christianp commented 4 months ago

I'm writing this issue at the end of the day so haven't spent the time to make a demo of this, but I'm logging it now in case you can tell me the answer anyway!

I noticed that Numbas seems not to destroy the R objects created when it runs code. For each session, we create Shelter and and REnvironment objects, run several blocks of code, and then run shelter.purge(), since that's the only method I could see that looked like it cleared memory.

However, something's still being retained between session - after running code that makes a vector of a million numbers in about 200 separate sessions, I start getting "can't allocate a vector" errors.

What else should I be doing?

georgestagg commented 4 months ago

You could try clearing the Global shelter at the same time as purging your own user Shelter:

webR.globalShelter.purge();

Without looking at the extension code to check, you could be hitting a situation where we're unable to protect R objects in the user Shelter for whatever reason, and so they're protected globally instead. We'd like to eliminate those situations eventually, but I know a few corner cases still exist.

You could also try explicitly asking R to invoke its internal garbage collector, after purging the shelters:

webR.evalRVoid("gc()");
christianp commented 4 months ago

It looks like purging the global shelter does fix it.

For reference, here's a minimal example that just runs the same code repeatedly in new shelters until it runs out of memory: https://webr-not-clearing-memory.think.somethingorotherwhatever.com/. On my PC, it fails after 25ish runs.

And here's a version that also purges the global shelter: https://webr-clear-memory-purge-globalshelter.think.somethingorotherwhatever.com/. I let it get to 100 runs before stopping.

Should I leave this issue open as a case where the objects aren't protected in the user shelter?

georgestagg commented 4 months ago

Thanks for the really clear examples! Yes, please leave this open for now.