jimp-dev / jimp-dev/jimp

Memory leak

Open
#906 0 comments 2 reactions 0 assignees View on GitHub
bug help wanted
Dominant language
TypeScript
Stars
14.7k
Forks
777
PR merge metrics
No merged PRs in 30d

Description

I'm using Jimp for a very simple thing, I read the uploaded file, if the size is over 300x300 pixels I resize it to 300x300 with `scaleToFit` and write the changed image to my server with `writeAsync`.

The memory spikes are crazy, and the big issue is that its not freeing the memory, it keeps high, I'm currently testing my app, but in real life my app would restart on daily basis when memory hit limit.

# Expected Behavior
Memory drop down to normal levels.

# Current Behavior
my normal memory of my program is around 75MB, after uploadig 1 image size of 5MB, memory spikes to 175MB and go down to 100MB, if i upload 5 different images with total of 13MB, the memory spikes to over 450MB and go back to 300MB, and stays like that.

## Steps to Reproduce
Here is my code that I use.

```
Jimp.read(file.data).then((image) => {
if (image.bitmap.width > 300 || image.bitmap.height > 300) {
image.scaleToFit(300, 300);
}

return image.writeAsync(tempLocation).then(() => {
image = undefined;
delete image;
return res.json({status: '200', data: {imageUrl: `${config.APP.HOST}/uploads/${fileName}`}});
}).catch((err) => {return res.json({err});});
}).catch((err) => {return res.json({err});});
```

I read the image, check if the size is over 300, if it is we `scaleToFit` to 300x300, write the image on our server for later use, and send back a successful response.

My upload functionality is only this, nothing is done except manipulating the image and saving to our server.

I also tried to remove the `writeAsync` functionality, and the spike still continue the same, so this must be an issue with `scaleToFit` to `read`.

I also tried to use `delete image` or set it to undefined, but it doesn't help.

I understood from other issues here that forcing the GC after I'm done will do the trick, but there must be an issue if it is not happening automatically.

[EDIT]
I tried to force GC:
```
return image.writeAsync(tempLocation).then(() => {
image = undefined;
Jimp = undefined;
delete Jimp;
delete image;

try {
if (global.gc) {global.gc();}
} catch (e) {
console.log('Error: the --expose-gc argument was missing: `node --expose-gc index.js`');
}
```

I tried multiple stuff but it didn't help, the memory still stay over 300MB, even after one hour, so it doesn't help.

Contributor guide

Open the contributing guide

Research direction

Start with the reported Node.js reproducer using Jimp.read, scaleToFit, and writeAsync, and measure memory after each step across repeated uploads. Trace the image lifecycle through those entry points to identify where retained memory is observed. Done means the reproducer no longer leaves memory elevated after processing images, with a regression test or documented measurement.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
backend, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.