Name: rmT116609 Date: 05/21/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 :
Using JPEGImageReader reset() is very slow since it calls System.gc(). The effect of System.gc() is not noticable if you read big images, but in a program that is supposed to read many small JPEG files per second this makes the system unusable.
Calling System.gc() is not needed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a JPEGImageReader
2. Read many small JPEG files with the same reader, calling reset() in between
each read (JPEGImageReader native code leeks memory if JPEGImageReader is reused without calling reset() in between)
3. Run the code with java -verbose:gc option turned on
I used a small JPEG file of size 1k (256 x 256 pixels).
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Full GC is only done when the GC system decides that it is necessary
ACTUAL -
Full GC is done at each rest making the system unacceptably slow.
[GC 399K->355K(1984K), 0.0275450 secs]
[GC 691K->462K(1984K), 0.0188700 secs]
[Full GC 857K->194K(1984K), 0.0989880 secs]
[Full GC 594K->203K(1984K), 0.0943940 secs]
[Full GC 602K->211K(1984K), 0.0866380 secs]
[Full GC 610K->194K(1984K), 0.1035630 secs]
and so on, one Full GC for each image.
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 < 100; i++) {
System.out.print('.');
reader.setInput(new FileImageInputStream(new File(args[0])));
reader.read(0);
reader.reset();
}
System.out.println("\ntook " + (System.currentTimeMillis() - start) +
" ms");
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
1. Get J2SE source code (src.jar)
2. Uncomment System.gc() from com.sun.imageio.plugin.jpeg.JPEGImageReader reset() method
3. Compile and patch rt.jar
(Review ID: 186034)
======================================================================