iFrankWu / thumbnailator

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

OutOfMemoryError: Java heap space / Builder.asBufferedImage #62

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Load 20 differents images (not necessarily large ones).

What is the expected output? What do you see instead?
BufferedImage thumbnail = Thumbnails.of(image).size(Integer.parseInt(width), 
Integer.parseInt(height)).scalingMode(scalingMode).outputQuality(quality).asBuff
eredImage();

Exception in thread "http-bio-8280-exec-9" java.lang.OutOfMemoryError: Java 
heap space
    at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:42)
    at java.awt.image.Raster.createInterleavedRaster(Raster.java:248)
    at java.awt.image.BufferedImage.<init>(BufferedImage.java:370)
    at net.coobird.thumbnailator.resizers.ProgressiveBilinearResizer.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)
    at net.coobird.thumbnailator.Thumbnails$Builder.asBufferedImage(Unknown Source)

What version of the product are you using? On what operating system? Which
version of Java (Sun/Oracle? OpenJDK?) ?
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)

thumbnailator-0.4.6

Eclipse.ini
-Xmn512m
-Xms1024m
-Xmx2048m
-Xss4m

Please provide any additional information below.
Issue 44 and 46 are kinda the same problem.

Original issue reported on code.google.com by lucasbme...@gmail.com on 2 Dec 2013 at 5:06

GoogleCodeExporter commented 9 years ago
Hello,

Thank you for filing this issue.
Sorry for taking long to get back to you.

I haven't experienced this issue in the past when I've dealt with multiple 
large images.

Could I get more information and clarification on when you've encountered this 
issue?

  1. Were the calls to `Thumbnails.of` made 20 times?
  2. What is `image`? Is it a single `BufferedImage`? Is it a `File`? Are they multiple of either?
  3. What were the values for the variables such as `width`, `height`, `scalingMode`, etc?

It is going to be hard for me to reproduce the issue without some more details 
on when the `OutOfMemoryError` was encountered.

Original comment by coobird...@gmail.com on 22 Dec 2013 at 4:36

GoogleCodeExporter commented 9 years ago
1. 
Yes, calls to Thumbnails.of were made 20 or more times. The entire function is 
called again, so everything including 'image' bellow is loaded again. 

2. 
Yes, 'image' is a BufferedImage:
>>>BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
There's no "file" on it. 

3. 
quality = 1;
scalingMode = ScalingMode.BILINEAR;
width = 750px;
height = 400px;
original image width is no bigger than 1800px, it may vary;
original image height is no bigger than 1800px, it may vary;

4. In addition:
Application server is apache-tomcat-7.0.30
The entire source code is attached. Significant lines lies between 132 and 195. 
The problem happens at line 163.

Hope it helps!

Original comment by lucasbme...@gmail.com on 26 Dec 2013 at 9:50

Attachments:

GoogleCodeExporter commented 9 years ago
Hi,

Once again, sorry it took long to get back to you.

I see that the Thumbnailator code is being called as part of an servlet. Are 
the 20 calls being made simultaneously? Or are they being called in a serial 
manner?

The reason I ask is because internally, in the 
`ProgressiveBilinearResizer.resize` method, there is a section of code that 
re-creates a new `BufferedImage` object, and that operation itself can use 
quite a bit of memory (width * height * 4 bytes), and it's possible that under 
some circumstances (such as having resizing operations occur at the same time 
-- perhaps multiple requests?) could cause exhaustion of the JVM heap.

Also I should add that between calls to Thumbnailator, there is no state being 
left in static fields and such, so making the 20 calls in succession should not 
cause size increases to the heap.

With those in mind, I was taking a look at the code, and have noticed that 
there appears to be some kind of caching code (which I'm guessing from the 
`imageResource.storeLocalCache` call) and I've been wondering if that could be 
using a lot of memory. I feel this may be one place to look into, because the 
`storeLocalCache` method is being handed a `BufferedImage` which is the raw 
image data, which can lead to a lot of memory being used -- basically, (width * 
height * 4) bytes will be used per image.

I'm having a hard time believing this problem is being caused by a memory leak 
in Thumbnailator.

To get to the bottom of the issue, I'd suggest using a profiling tool like 
`jvisualvm` or such and see what's taking a lot of space on the JVM heap, which 
is probably the cause for the `OutOfMemoryError`.

------

On a separate note, Thumbnailator by default compares the input and output 
image dimensions to determing the scaling mode to use, similar to the code 
you've attached.

If you're curious, the code can be found in the `DefaultResizerFactory` class:
http://code.google.com/p/thumbnailator/source/browse/src/net/coobird/thumbnailat
or/resizers/DefaultResizerFactory.java

Original comment by coobird...@gmail.com on 19 Jan 2014 at 2:25