WebAssembly/design

Freeing/Shrinking memory

maierfelix opened this issue ยท 14 comments

I have a Wasm project which parses a large chunk of textual data (~40mb). First, I reserve enough space to write the data over to Wasm's memory. Next, I run the Wasm module and process the data.

The problem is, that freeing the input/output memory doesn't actually shrink Wasm's memory. The memory keeps growing based on the largest allocation. In my project, I eventually end up having +200mb of wasted RAM.

  • Are there any plans to support memory shrinking?
  • I would be fine with a way to explicitly destroy a Wasm instance (so garbage collecting all its memory), but couldn't find one
Macil commented

I would be fine with a way to explicitly destroy a Wasm instance (so garbage collecting all its memory), but couldn't find one

I assume they should be garbage-collectable, so an instance should go away if you drop all references to it. (If for some reason a browser doesn't implement this correctly, a workaround would be to spawn a web worker or an iframe and use the Wasm instance inside of it, and then dispose of the web worker or iframe when you're done with it.)

dtig commented

There is nothing in progress to support memory shrinking right now, though it sounds like the issue you are facing has more to do with memory management in the engine. An instance object should be collected when the references to it are dropped, but when/how will depend on the specifics of your application as well as the engine you are running on. I would suggest following up on issue trackers for the engine that you are running on with more specifics.

binji commented

Shrinking memory is potentially a future feature, though it currently is not being discussed. Perhaps multi-memory could help as well. Closing, since there is nothing actionable for the design repo.

It's a good practice in the general sense, to make everything that is creatable be easily destroyable. ๐Ÿ‘

juj commented

Shrinking memory is potentially a future feature, though it currently is not being discussed. Perhaps multi-memory could help as well. Closing, since there is nothing actionable for the design repo.

I find it odd that this was closed - there would certainly be actionable work for the design repo for this:

  • discuss shrinking memory here
  • discuss support for unmapping memory pages (I recall this has been proposed in the past, did that get wind?)

Or I wonder if there are GitHub issues already for discussing either of the above two? (maybe link to them here?)

binji commented

Typically we use the design repo to discuss a new design for such a feature. This seemed more like a question that was answered. That said, I'm fine keeping it open if we want to use this issue to discuss the feature.

juj commented

Gotcha, that makes sense. I am just curious if releasing memory conversations have recently occurred elsewhere? Has there been work towards that that would've occurred?

binji commented

I haven't seen any -- maybe others know of a recent discussion?

My visitors spend hours on my website without reloading it.

My wasm program runs once every 5 minutes, for 0.5 seconds each time. It is called by a synchronous JS function, which expects the output right after the wasm finishes. During the execution, the wasm program needs 700 MB of RAM.

I would like to release these 700 MB when the wasm program does not run. What JS object should I release (remove references to)? Next time my JS function runs, I want to run the wasm program again (in a synchronous way).

I was thinking about recompiling WASM each time my JS function runs, but all current browsers compile WASM asynchronously. Is there anything else I can do?

I tried these lines, but they do nothing:

wasm.instance.exports.memory.buffer = new ArrayBuffer(10);
wasm.instance.exports.memory = new WebAssembly.Memory({initial:10});
penzn commented

@photopea you can re-instantiate module with new memory, though that would effectively recompile it. I've created #1396 from your question.

@photopea I dont mind re-instantiating or re-compiling (my Wasm is usually under 30 kB), as long as it can be done synchronously (as most of my JS program is synchronous at the moment). Do you know why browsers don't allow synchronous compilation (on the same core, without event listeners on the "compiled" event)?

penzn commented

I am not sure how to synchronously compile a module, but seems like you might be able to just switch the memory out: #1396 (comment)

Hi everyone, did any one figure out a solution to this?

I have an issue where new/delete of large arrays is causing memory fragmentation due to limitations in the wasm memory model (see #1397 )

we need a way to collect all and allow application memory to shrink when done with long running calculations