United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6472925 OutOfMemoryError fails to generate stack trace as it now ought
JDK-6472925 : OutOfMemoryError fails to generate stack trace as it now ought

Details
Type:
Bug
Submit Date:
2006-09-20
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
windows_xp
Sub-Component:
runtime
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
hs21 (b02)

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

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

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.
                                     
2006-09-20
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.
                                     
2010-09-02
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.
                                     
2011-02-03
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.
                                     
2011-02-03
EVALUATION

New message:

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

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



Hardware and Software, Engineered to Work Together