-
Bug
-
Resolution: Fixed
-
P3
-
1.4.2
-
tiger
-
x86
-
linux
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2169098 | 1.4.2_19 | Abhijit Saha | P3 | Resolved | Fixed | b04 |
JDK-2166500 | 1.4.2_18-rev | Nikolay Gorshkov | P3 | Resolved | Fixed | b12 |
Name: rmT116609 Date: 05/22/2003
FULL PRODUCT VERSION :
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b19)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b19, mixed mode)
FULL OS VERSION :
Linux xxx.xxx.xxx.xxx 2.4.20-13.9 #1 Mon May 12 10:55:37 EDT 2003 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
Reusing the same JPEGImageReader to read multiple JPEG images leeks memory.
NOTE: This is not related to the bug that JPEGImageReader leeks memory if dispose() is not called after finishing with the JPEGImageReader. If an JPEGImageReader is reused if leeks memory for good and the memory cannot be reclaimed with subsequent call to dispose().
Since the leek is very small (<1k per image) it will not be noticed by normal client code but with code that is meant to process millions of images over a long period of time, it will be noticable.
The memory leek occures in the native part of the JPEGImageReader where the reference to the object is lost.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a JPEGImageReader
2. Read multiple (>100000) small images with the JPEGImageReader, do not call reset() in between reads
3. Run the code with -runhprof switch
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No memory should be leeked
ACTUAL -
Each time the JPEGImageReader is reused a small byte buffer (size depends on the image size) is leeked.
Here is a snipet from the java.hprof.txt SITES section showing the memoryleek
SITES BEGIN (ordered by live bytes) Sun May 18 15:12:47 2003
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
6 3.02% 80.41% 51744 66 51744 66 840 [B
You can tell it is a memory leek because non of the 66 objects (there are 66 iterations in the attached test code) is never freed.
and the associated stack trace:
TRACE 840:
java.awt.image.DataBufferByte.<init>(DataBufferByte.java:42) com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:963)
com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:853)
javax.imageio.ImageReader.read(ImageReader.java:919)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.imageio.*;
import javax.imageio.stream.*;
import java.util.*;
import java.io.*;
public class JPEGImageReaderTest {
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("USAGE: java JPEGImageReaderTest <jpegfile>");
System.exit(1);
}
try {
ImageReader reader =
(ImageReader) ImageIO.getImageReadersByFormatName("jpeg").next();
long start = System.currentTimeMillis();
for (int i = 0; i < 66; i++) {
System.out.print('.');
reader.setInput(new FileImageInputStream(new File(args[0])));
reader.read(0);
}
reader.dispose();
System.out.println("\ntook " + (System.currentTimeMillis() - start) +
" ms");
System.gc(); System.gc();
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
1. Do not reuse JPEGImageReader - this option means that you have to instantiate a new JPEGImageReader for every image... slow
2. call reset(), but since reset() has a call to System.gc() in it, it is very slow.
(Review ID: 186036)
======================================================================
- backported by
-
JDK-2166500 Reusing JPEGImageReader to read multiple JPEG images leaks memory
- Resolved
-
JDK-2169098 Reusing JPEGImageReader to read multiple JPEG images leaks memory
- Resolved