ImageIO.read() causes OutOfMemoryError

The problem

Few days ago, a reader contacted me with a problem he had in a piece of code. The code was creating thumbnails from images and was throwing an OutOfMemoryError after few dozens of images.  Here is the simplified code, line 26 throws OutOfMemoryError:

And here is the stacktrace with the OutOfMemoryError:

The cause of the OutOfMemoryError

The cause of that problem is not obvious. The stacktrace (and the title of this article) is somewhat misleading. Here is what happens: The call to fullSizeImage.getScaledInstance() (lines 33-34) produces a smaller image thumbnail, but that thumbnail object keeps a reference to the fullSizeImage. Since JPEG files are highly compressed, reading and parsing them takes a significant amount of memory and that memory can never be freed.

The solution: Do not use Image.getScaledInstance()

The solution was to replace the call to fullSizeImage.getScaledInstance() with the lines 34-38 highlighted below. That solution allowed the code to read thousands of images, because the fullSizeImage was no longer kept in memory.

References

From Oracle’s website: How do I create a resized copy of an image?

For this particular problem, I did not need to produce a heap dump, because the code was small enough. With a few tests and a few searches on Google, I could figure-out what was happening. However, if you have no idea where the OutOfMemoryError comes from, you may want to read this article: How to fix java.lang.OutOfMemoryError: Java heap space