westei / thumbnailator

Automatically exported from code.google.com/p/thumbnailator
Other
0 stars 0 forks source link

Implement a workaround for common OutOfMemoryError cases #69

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
There have been increasing number of reports of `OutOfMemoryError`s occurring 
when using Thumbnailator. (Issue 1)

In many cases, this is a result of trying to resize large input images, which 
causes Thumbnailator to read the entire image to the JVM heap memory, resulting 
in the `OutOfMemoryError`s due to the heap being filled up.

A permanent fix to the problem is better achieved by changing the Thumbnailator 
architecture to not require loading the entire image to memory before resizing 
the image, but this will require a comprehensive rewrite, which is planned for 
a later release.

To address the `OutOfMemoryError` in a more timely manner, a temporary 
workaround should be possible by examining the image metadata to find out the 
image size, and accordingly apply a subsampling on the read operation to reduce 
the amount of memory used when reading the image.

Original issue reported on code.google.com by coobird...@gmail.com on 4 May 2014 at 5:36

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago

Thank you for prioritizing this issue.

We keep encountering this issue in the following scenarios:

1. Resizing

java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:42)
    at java.awt.image.Raster.createInterleavedRaster(Raster.java:253)
    at java.awt.image.BufferedImage.<init>(BufferedImage.java:365)
    at net.coobird.thumbnailator.resizers.ProgressiveBilinearResizer.resize(Unknown Source)
    at net.coobird.thumbnailator.resizers.Resizers.resize(Unknown Source)
    at net.coobird.thumbnailator.makers.ThumbnailMaker.makeThumbnail(Unknown Source)
    at net.coobird.thumbnailator.makers.FixedSizeThumbnailMaker.make(Unknown Source)
    at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source)

2. Reading

java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:58)
    at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397)
    at java.awt.image.Raster.createWritableRaster(Raster.java:938)
    at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056)
    at javax.imageio.ImageReader.getDestination(ImageReader.java:2879)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:943)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:915)
    at javax.imageio.ImageReader.read(ImageReader.java:923)
    at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.read(Unknown Source)
    at net.coobird.thumbnailator.tasks.SourceSinkThumbnailTask.read(Unknown Source)
    at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source)

Original comment by M.Kirkus...@gmail.com on 5 May 2014 at 5:32

GoogleCodeExporter commented 9 years ago
Do you have a time frame for when the workaround can be available?

Thanks

Original comment by M.Kirkus...@gmail.com on 6 May 2014 at 5:50

GoogleCodeExporter commented 9 years ago
Could you please let us know when if possible the workaround will be available?

Original comment by M.Kirkus...@gmail.com on 13 May 2014 at 3:51

GoogleCodeExporter commented 9 years ago
I've started implementing the fix, but it turns out that the image quality will 
degrade a bit when this fix is enabled.

I'm hoping to reduce the amount of quality degradation to a minimum, as I 
intended to automatically enable this workaround for everyone.

Also, it turns out that I've been quite busy lately, and have not been able to 
make progress. I definitely cannot get a fix out until at least May 24th at the 
very earliest.

Please understand that I am writing Thumbnailator during my free time -- time 
which can be very limited at times due to other priorities.

Original comment by coobird...@gmail.com on 14 May 2014 at 4:41

GoogleCodeExporter commented 9 years ago
I highly appreciate your endeavor on this issue and that you are doing this on 
your free time. Sorry if I added a bit too much emphasis in the priority of 
this issue.

This is a very good tool and we really like using it.

Please let me know when the workaround is available so I can test it and let 
you know.

Kind Regards

Original comment by M.Kirkus...@gmail.com on 19 May 2014 at 4:56

GoogleCodeExporter commented 9 years ago
Hi,

Have you managed to develop a fix for us and if you have a time frame when this 
will be available?

Kind Regards

Original comment by M.Kirkus...@gmail.com on 27 May 2014 at 4:04

GoogleCodeExporter commented 9 years ago
A temporary workaround has been created so that under the following conditions, 
Thumbnailator will invoke code to load a smaller image to memory from the 
source image when creating a thumbnail:

 * The JVM is started with the VM argument: `-Dthumbnailator.conserveMemoryWorkaround=true`
 * Both height and width have dimensions larger than 1800 pixels
 * The expected size of the source image will take up more than 1/4 of the available JVM free memory

The caveat is that there will be a noticeable degradation in the image quality 
when using this workaround. However, the memory used should be reduced when 
creating thumbnails from large images.

The reason I added the requirement to start the JVM with an VM argument is so 
that users experiencing `OutOfMemoryError`s can enable the workaround as 
needed, as if this workaround was enabled by default, everyone will notice a 
drop in image quality.

The code has been pushed to the `feature-oom-workaround` branch, and has not 
been merged to any other release branches at this time.

Also, I've attached a JAR file with the temporary workaround included. THIS 
SHOULD NOT BE CONSIDERED A FINAL RELEASE.

Original comment by coobird...@gmail.com on 1 Jun 2014 at 4:50

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you for the quick turnaround on this.

We have tested and it resolves the OOM issues. 

Kind Regards

Original comment by M.Kirkus...@gmail.com on 6 Jun 2014 at 2:17

GoogleCodeExporter commented 9 years ago
Thank you for trying out the workaround!

Original comment by coobird...@gmail.com on 19 Jun 2014 at 3:41

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Does this approach create a spike in non-heap memory for you (ie, in the amount 
of memory from the OS's perspective)? I have a similar approach in some of my 
code and am seeing that. Specifically, the native method 
com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage takes a huge amount of 
memory for large images (more than a gig), none of which appears in 
jmap/JVisualVM/etc. As soon as that method returns, the memory is reclaimed.

Original comment by yuval.sh...@gmail.com on 14 Aug 2014 at 7:19

GoogleCodeExporter commented 9 years ago
Workaround does resolve the issues for the large files I've encountered as 
well. Thanks!

Original comment by wilkerso...@gmail.com on 8 Oct 2014 at 8:40

GoogleCodeExporter commented 9 years ago
This workaround will be merged into Thumbnailator 0.4.8.

Original comment by coobird...@gmail.com on 26 Oct 2014 at 3:26

GoogleCodeExporter commented 9 years ago
The workaround has been included in Thumbnailator 0.4.8.

See project changes for details:
https://code.google.com/p/thumbnailator/wiki/Changes

Original comment by coobird...@gmail.com on 1 Dec 2014 at 3:01