Comments (10)
Hopefully, in the future, wasm-vips can leverage Igalia's "Ref C++", which manages the lifetime of objects in a more convenient way.
https://github.com/Igalia/ref-cpp#destructors-and-finalizers
You're right that there's a lack of documentation on this subject in the meantime. I'll have a look at adding this, hence the "documentation"-label.
vips.shutdown()
is only useful on non-web environments. It was added to shutdown Emscripten's thread pool, which would otherwise prevent the event loop from exiting.
Note that setAutoDeleteLater()
is currently opt-in, so you don't need to pass false
to that function outside the playground.
from wasm-vips.
v0.0.2 now available with a fix for this. Docs for memory management have yet to be created.
from wasm-vips.
The page seems to use up a lot of memory according to Chrome's task manager. It grows to 1.2GB usage at 131 images, and then crashes. I thought it might have had to do with creating all those PNG blobs and not revoking the URLs after processing, but removing the URL.createObjectURL
stuff (so loop body is just fetch
and then bicubicResizeAndCenterCrop
) doesn't fix it.
from wasm-vips.
Hi @josephrocca,
Currently it's required to call delete()
on every image instance that is returned from wasm-vips. The Emscripten docs also provides some explanation for this:
https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management
It's very inconvenient with operation chains, unfortunately. The emscripten-auto-deletelater.patch
patch (which I still need to upstream) makes this less difficult by calling deleteLater()
automatically during the construction of handles, you only need to do this within Module.preRun
:
wasm-vips/playground/src/playground-runner.html
Lines 61 to 64 in 1970d48
After that, you can call cleanup()
to clean up the used resources. For example, the playground does this before each run in order to clean up the previous run (if any):
wasm-vips/playground/src/playground-runner.html
Lines 26 to 27 in 671f05b
This is also used within unit tests, where resources are cleaned up after each test:
wasm-vips/test/unit/test_arithmetic.js
Lines 29 to 31 in 671f05b
Given this information, I could resolve this locally by doing this within that playground link:
@@ -10,6 +10,7 @@
img.title = url;
document.getElementById('output').appendChild(img);
console.log(nProcessed++, url);
+ cleanup();
}
console.log("FINISHED");
})();
Note that I haven't documented this yet because I wasn't sure if Embind will be used in later versions, see:
https://github.com/kleisauke/wasm-vips/projects/1#card-44661960
from wasm-vips.
@kleisauke Ahh, I see thanks for that. If I want to just "deal with" the chaining inconvenience so I can do the cleanup with the bicubicResizeAndCenterCrop
function, how would I do that? The code below throws "BindingError: Object already scheduled for deletion" at im1.delete()
.
async function bicubicResizeAndCenterCrop(blob) {
let im1 = vips.Image.newFromBuffer(await blob.arrayBuffer());
// Resize so smallest side is 224px:
let resizeFactor = 1;
if (im1.width > im1.height) {
resizeFactor = 224 / im1.height;
} else {
resizeFactor = 224 / im1.width;
}
let im2 = im1.resize(resizeFactor, { kernel: vips.Kernel.cubic });
// crop to 224x224:
let left = (im2.width - 224) / 2;
let top = (im2.height - 224) / 2;
let im3 = im2.crop(left, top, 224, 224)
let outBuffer = new Uint8Array(im3.writeToBuffer('.png'));
im1.delete();
im2.delete();
im3.delete();
return new Blob([outBuffer], { type: 'image/png' });
}
Also, not on topic, but maybe not big enough for it's own issue: Should the vips.shutdown()
method return a promise? (and should I be await
ing the delete
s above?)
from wasm-vips.
setAutoDeleteLater(true)
and delete()
are mutually exclusive. You'll need to pass the ?disableAutoDelete
query string in that playground if you want to control memory management using delete()
.
Should the
vips.shutdown()
method return a promise? (and should I beawait
ing thedelete
s above?)
I'm not sure if vips.shutdown()
can be made asynchronous. Both calls needs probably be done synchronous.
wasm-vips/src/vips-emscripten.cpp
Lines 46 to 48 in 84a86eb
https://github.com/emscripten-core/emscripten/blob/eea4056bb71493ae388a1cc22b2bda07cc4932ef/src/preamble.js#L399
https://github.com/emscripten-core/emscripten/blob/eea4056bb71493ae388a1cc22b2bda07cc4932ef/src/embind/embind.js#L1876
from wasm-vips.
Ah gotcha, thanks! I wonder if this could all be made more intuitive with WeakRef
s? In any case, in the meantime it would definitely be worth adding a note about deletion stuff to the readme, because it's unusual in JavaScript land to have to worry about memory management, so I'm guessing most people would assume that image objects are garbage collected automatically. Thanks again!
Oh, and RE the shutdown question, I thought maybe the workers wouldn't have been guaranteed to be terminated after vips.shutdown()
has been executed. But if it can all be done synchronously, then that's fine. (Or maybe I misunderstand what the shutdown method is supposed to do)
from wasm-vips.
@kleisauke Looks like I still have a leak somewhere. Here's a minimal reproduction - it's basically the same code as before, but I'm just loading one image and resizing it over and over.
Accoding to Chrome's Task Manager, the tab starts out with a memory footprint of about 200MB and steadily grows to ~1GB after processing ~7000 iterations and then crashes with the same OOM error:
If there's a deeper problem at play here that could take some time to fix, then is vips.shutdown()
the right method to use if I want to e.g. restart vips every 1000 iterations? And if so, is there a way to find out when vips is finished disposing/terminating all the workers/modules/memory? Or does vips.shutdown()
somehow do it synchronously?
Edit: If I add the code below within the for
loop, then it gets to about 13000 iterations, but then the whole browser tab crashes, instead of just throwing an error in the console.
if(nProcessed % 1000 === 0) {
vips.shutdown();
await new Promise(r => setTimeout(r, 5000));
vips = await Vips();
vips.EMBIND_AUTOMATIC_DELETELATER = false;
}
from wasm-vips.
I could reproduce this and was able to fix it with commit 89e167f. Here's an updated playground link that now runs steady for me. Thanks for reporting this!
Regarding, vips.shutdown()
, I would use it as a last resort on the web. I'm not sure if it's safe to restart libvips in WebAssembly, as vips_init()
can't be called after vips_shutdown()
. That's probably why the browser tab crashes.
As an aside, commit 02b9215 replaces the EMBIND_AUTOMATIC_DELETELATER
property with the setAutoDeleteLater
function. I updated my previous comments to reflect this.
from wasm-vips.
Great, looking good so far on my end. Thanks for working to fix that so quickly!
It would definitely be nice to have some sort of vips.destroy()
/vips.dispose()
method that completely cleans up and removes wasm-vips
in a "safe" way. This would be especially important in long-running single-page applications where, e.g. wasm-vips
may only be required temporarily for a small part of the app's functionality.
(P.S. Thanks for that sneaky scale
factor simplification ^^)
from wasm-vips.
Related Issues (20)
- Does this work with `sharp`? HOT 3
- `heifsave` is not defined HOT 3
- `wasm-vips` is unstable on Node `18.14.2+` and `19.4.0+` HOT 11
- Unstable on Deno HOT 2
- Playground feature request: ability to import file from disk HOT 3
- `WasmTrapJSTypeError` while loading an SVG when building with LTO HOT 3
- Docker compilation error HOT 6
- setup wasm-vips for next.js/react HOT 3
- TS types improvements HOT 3
- writeToBuffer increases RSS size till OOMKilled HOT 3
- Not working on deno deploy HOT 1
- ab [vips::Error]: no such operation pdfload_buffer VipsOperation: class "pdfload_buffer" not found HOT 1
- JPEG 2000 Support HOT 1
- Errors with vite HOT 27
- No paths work when reading files (Deno) HOT 2
- Promise remains in pending mode HOT 3
- Error `heifload: ignoring nclx profile` when converting to AVIF and resizing HOT 4
- Add progress information HOT 3
- Error: need to see wasm magic number HOT 1
- Enhancement βΒ more modular loading HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wasm-vips.