JDK-6472925 : OutOfMemoryError fails to generate stack trace as it now ought
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-09-20
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 Other
7Fixed hs21Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
One of the stated goals of Mustang is to "Improve the diagnosability of java.lang.OutOfMemoryError".

In particular:
	"For example, you should now see a stack trace when an OutOfMemoryError is thrown when the heap is full."
	http://java.sun.com/developer/technicalArticles/J2SE/Desktop/JavaSE6_build39.html
  See also:
	http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4753347
which claims that mustang(b34) fixed this.

But I have a simple test class (see below) which should generate an OutOfMemoryError.  But not only does it fail to generate the long promised OutOfMemoryError stack trace, it even fails to notify me that an OutOfMemoryError occured at all--it simply says that an Exception happened.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Enter the following code into a file named MemErrDiagnose.java
Then compile and run it on a command line (or in your favorite IDE) using

javac MemErrDiagnose.java

java  -classpath ./  -Xmx10m  MemErrDiagnose


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Running the java command described above should result in a few lines like

allocate #1
allocate #2

followed by a complete stack trace of the OutOfMemoryError.  The OutOfMemoryError should also state that it was specifically due to lack of heap space.
ACTUAL -
Running the java command described above actually produced just the following output

allocate #1
allocate #2
Exception in thread "main"

That last line is the problem: it is totally generic (not even a OutOfMemoryError) and it lacks a stack trace.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.*;

public class MemErrDiagnose {
	
	private static final Random random = new Random();
	private static long count = 0;
	private static final List<Object> list = new LinkedList<Object>();
	
	public static void main(String[] args) {
		try {
			while (true) {
				allocate();
			}
		}
		catch (Throwable t) {
			System.err.println( t.getClass().getName() );
			t.printStackTrace( System.err );
		}
	}
	
	private static void allocate() {
		System.out.println( "allocate #" + (++count) );
		int n = random.nextInt(1000 * 1000);
		for (int i = 0; i < n; i++) {
			list.add( new Object() );
		}
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None that I know of.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/rev/fb539912d338
09-02-2011

EVALUATION New message: ... Exception in thread "main" Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
04-02-2011

EVALUATION To be clear, the fix I'm going to put back for this bug just adds an additional diagnostic. Getting a stack trace from out of memory while the java program is still out of memory isn't possible.
03-02-2011

EVALUATION This isn't a bug. We can't generate a stack trace because the VM calls into Java to do that and since this test doesn't release any memory, Java is Out Of Memory. If we get an exception during the Java unhandledException() call we could print an additional message: ... allocate #15 allocate #16 Exception in thread "main" . Uncaught exception of type java.lang.OutOfMemoryErr or. Not sure how this got on the 7-pool list.
03-02-2011

EVALUATION I agree with the previous evaluation, the only "bug" here is that the Java level exception handling code can encounter secondary exceptions for which there is no handling. At present in the VM we simply clear any pending exception, but we could instead print a warning to stderr.
02-09-2010

EVALUATION The exception and stack trace are printed by ThreadGroup's uncaughtException method. The issue here is that the test consumes every word in the heap and the printing of the exception and stack trace (which is done by System.err) is also throwing an OutOfMemoryError which aborts the printing of the original exception and stack trace. It may be worth adding code to JavaThread::exit to print some diagnostic for the case that the uncaught exception handler also throws an exception.
20-09-2006