2

I wrote the following code:

public class JavaErrorTest {    
    public static void main(String[] args) {
        if (1 < 2) {
            throw new OutOfMemoryError();
        }
    }       
}

Then I invoke it like:

$ java -XX:OnError="echo %p" JavaErrorTest

And in my console, I get the following:

Exception in thread "main" java.lang.OutOfMemoryError
    at JavaErrorTest.main(JavaErrorTest.java:5)

Somehow, I suspect that the -XX:OnError JVM option is not being picked up. I'm invoking java using cygwin, using jdk 1.6.0_30, running under Windows 64 bits.

What am I doing wrong?

EDIT

Following command produces the same output:

$ java -XX:OnOutOfMemoryError="echo %p" JavaErrorTest
chahuistle
  • 2,627
  • 22
  • 30

3 Answers3

6

I believe -XX:OnError is meant to be used for fatal virtual machine errors - i.e. "something is wrong with the JIT, we've generated invalid code" - not "an unhandled exception has been thrown". (Even if this had been thrown by the VM, I wouldn't count this as a VM error.)

Basically I believe it's for debugging the VM, not user code.

EDIT: When using -XX:OnOutOfMemoryError I see it doesn't use the flag value when you explicitly throw it from user code (which you shouldn't be doing anyway) but does use it when you genuinely exhaust memory. For example:

public class Test {
    public static void main(String[] args) {
        String[] x = new String[10000000];
        for (int i = 0; i < x.length; i++) {
            x[i] = new String(new char[10000]);
        }
    }       
}

Run with:

~ $ java -XX:OnOutOfMemoryError="echo %p" Test
#
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="echo %p"
#   Executing /bin/sh -c "echo 29712"...
29712
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3057)
    at java.lang.String.<init>(String.java:196)
    at Test.main(Test.java:5)

(This still isn't shown for OnError though, which is fair enough - again, it's not showing a bug in the VM.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

In order for the -XX:OnErrorto be triggered, you will need to use -XX:+CrashOnOutOfMemoryError also.

0

Try the following, though it doesn't trigger the same error.

public static void main(String... args) {
    long[] l = new long[Integer.MAX_VALUE];
}  

This should trigger the same error.

List<byte[]> bytes = new ArrayList<byte[]>();
while (true)
    bytes.add(new byte[64 * 1024 * 1024]);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130