High memory usage on subsequent image reads from Aspose.Imaging

Hi Guys,

We are using Aspose.Imaging for JAVA to load images, after a while the Aspose.Imaging library starts to consume more memory for the same images and this leads to out-of-memory errors and after restarting the service the memory usage return to normal and starts increasing gradually again.

To reproduce the issue, you need a memory profiler, you need 3 big image files (we used 2 100mb tiff images, and 1 50mb tiff image), and then run 5 threads in parallel where you load each image using Aspose.Imaging Image.load, save each image to the output stream using Image.save and PdfOptions then dispose of the image, and using that output stream save it to the main pdf document, and finally save the main pdf document to the disk, after all threads finish, repeat the run for 3 times, after each time you will notice from the memory profiler that loading the same images on the later requests will consume increasing memory.

The expected is to consume the same memory value for the subsequent image loads for the same set of images.

Sample code:
Image image = Image.load(inputStream); // image input file input-stream
try (outputStream) {
image.save(outputStream, new PdfOptions());
} finally {
image.dispose();
}
try (InputStream in = createInputStream(outputStream)) {
document.getPages().add(new Document(in).getPages());
}

Note: we didn’t identify it as a memory leak, as the GC clears the memory as expected after each run, and for the new runs the memory consumption increased during the Image.load call.

@ahashem, Could you please attach the files with which the problems are, and also tell me version of the library used?

We are using Aspose 21.12
You can use any image files, we have reproduced it with many samples, you can use the 50mb file from this website multiple times: Sample TIFF Files Download - Get Examples Instantly

@ahashem
Hello!
Yes, this issue is a known unpleasant issue. To minimize memory consumption the best way is to avoid using Image.load(InputStream) and Image.save(OutputStream). The most optimized way is to use the methods Image.load(String path) or Image.load(RandomAccessFile file).
Nevertheless, we are going to optimize the method Image.load(InputStream)

1 Like

Thanks @evgsidenko, we will try to see if it’s possible to switch to these methods and let you know if we face the same issue again

1 Like

Hello again,

One more question, is this bug exists in all Aspose libraries (i.e. Aspose.PDF)? should we always avoid the input stream variations of Aspose methods?

Thanks in advance.

@ahashem If you want to know specifics of usage of Aspose.PDF, please ask this question in an Aspose.PDF related forum:

Hi, we switched from InputStream to file path string, but we added image.resize(X, Y) to our code before image.save and now the high memory usage is happening because of image.resize, is this a known issue? can you please provide a workaround?

Image image = Image.load(inputFilePath);
try {
image.resize(595, 842);
image.save(outputFilePath, new PdfOptions());
} finally {
image.dispose();
}

P.S.: we removed the resize and still faced the memory issue.

Hi, @ahashem!
The growing memory usage is a normal and predictable result of resizing. Because before resizing all pixels of the image are loaded into memory then resized according to the chosen algorithm and stored in memory until Image.dispose() or Image.close() is called.
You can set a limit of using memory for pixels using LoadOptions.setBufferSizeHint(max_mem_in_MB)

for example

LoadOptions loadOptions = new LoadOptions();
loadOptions setBufferSizeHint(500); // limit is 500MB
Image image = Image.load(inputFilePath, loadOptions);
try {
  image.resize(595, 842);
  image.save(outputFilePath, new PdfOptions());
} finally {
  image.dispose();
}

This passed local testing, hopefully it will be the same on production, thanks so much

1 Like