Name: nt126004 Date: 03/04/2003
FULL PRODUCT VERSION :
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
Memory allocation doesn't wait for finalization to catch up.
Almost all programs run more than 1 thread which is creating objects, meanwhile only one thread is finalizing them, eventually OutOfMemoryErrors are thrown at almost random places throughout the code, making the code extremely fragile.
Changing VM paramters to alter Garbage Collector behaviour makes no difference, the code fails no matter what the parameters. Increasing the max heap size only delays the problem.
This problem only started to be really bad when JDK 1.4 came out. The cause of this is that many of the new imageio and nio classes have finalize methods causing them to require finalizing before they can get garbage collected. Despite the fact the the Finalizer thread runs at a higher priority, these new classes still block for a short amount of time hence finalization is getting blocked.
The more threads allocating objects requiring finalization the worse the problem gets.
Some of the imageio classes are using several meg of memory, which could easily be garbage collected before finalization was run. Simply have the image classes hold a sub object with a finalize method and a handle such that it can call dispose instead of the image classes directly having the finalize method and hence having to wait for the Finalizer thread before they release several megs of memory. The problem still needs to get fixed, but this would atleast give programs using the imageio a chance to continue without the bug getting fixed.
Related Bugs: 4811982, 4640743, 4239841
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run code and wait for the OutOfMemoryError
EXPECTED VERSUS ACTUAL BEHAVIOR :
With each of the 2 new threads only using 1 object each, I would expect this code to run forever without a problem. The code only needs about 2MB to run, yet it throws OutOfMemoryErrors no matter how much memory the VM allocates to it.
Thread dies due to OutOfMemoryError.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class TestObject {
private byte[] bytes;
private static int createdCount;
private static int finalizedCount;
public TestObject() {
bytes = new byte[1000000];
try {
Thread.sleep(500);
}
catch (InterruptedException ex) {
}
System.out.println("Created " + ++createdCount);
}
public void finalize() {
try {
Thread.sleep(500);
}
catch (InterruptedException ex) {
}
System.out.println("Finalized " + ++finalizedCount);
}
}
class TestThread extends Thread {
public void run() {
while (true) {
TestObject testObject = new TestObject();
// do something with object
testObject = null; // allow it to get garbage collected
// continue with something else
}
}
}
public class Test {
public static void main(String[] args) {
new TestThread().start();
new TestThread().start();
}
}
---------- END SOURCE ----------
(Review ID: 182033)
======================================================================