This section describes stack overflow testing programs and test results with HotSpot Client VM, HotSpot Server VM and JRockit.
The StackOverflowError is a JVM exception thrown
when a stack overflow occurs because an application recurses too deeply.
I wrote the following 3 programs to try this exception:
/**
* RecursiveCrash.java
* Copyright (c) 2002 by Dr. Herong Yang, herongyang.com
*/
class RecursiveCrash {
public static void main(String[] a) {
sub();
}
private static void sub() {
sub();
}
}
/**
* RecursiveCrash1.java
* Copyright (c) 2002 by Dr. Herong Yang, herongyang.com
*/
class RecursiveCrash1 {
static long n;
public static void main(String[] a) {
n = 0;
sub();
}
private static void sub() {
n++;
try {
sub();
} catch (StackOverflowError e) {
System.out.println("Stack overflow error at: "+n);
}
}
}
/**
* RecursiveCrash2.java
* Copyright (c) 2002 by Dr. Herong Yang, herongyang.com
*/
class RecursiveCrash2 {
static long n;
public static void main(String[] a) {
n = 0;
try {
sub();
} catch (StackOverflowError e) {
System.out.println("Stack overflow error at: "+n);
}
}
private static void sub() {
n++;
sub();
}
}
RecursiveCrash is simple, effective, and ready to crash any JVM.
RecursiveCrash1 is designed to catch the exception, and output the depth of the
recursion.
RecursiveCrash2 is an improvement to reduce the nested try statements.
All 3 programs were compiled with J2SDK 1.4.0_02 and executed with -Xms2m and
-Xmx64m options. Here is the summary of the execution results:
RecursiveCrash:
HotSpot Client:
at RecursiveCrash.sub(RecursiveCrash.java:6)
(repeated many times)
HotSpot Server:
at RecursiveCrash.sub(RecursiveCrash.java:6)
(repeated many times)
JRockit:
java.lang.StackOverflowError
at RecursiveCrash.sub()V(Unknown Source)
(about 35 lines of the same message)
JRockit with Management Server:
java.lang.StackOverflowError
at RecursiveCrash.sub()V(Unknown Source)
(about 35 lines of the same message)
java.lang.IllegalMonitorStateException
at java.lang.Object.getMonitorIndexWithCheck(Ljava.lang.Object;
Ljava.lang.Thread;)I(Unknown Source)
RecursiveCrash1:
HotSpot Client:
Stack overflow error at: 6740
HotSpot Server:
Stack overflow error at: 6113
JRockit: The execution hanged. System Task Manager showed 99% CPU usage and 9644K
memory usage. Ctrl-C did not end the process. I had to use the Task Manager to
end it.
JRockit with Management Server: Same result as the JRockit without Management
Server.
JRockit was not able to report the line number of the source code where
the exception occurred.
With the nested try statements included at each level of the recursive
call stack, JRockit was not able to terminate the execution.
Without the nested try statements, HotSpot Clien was able to perform
about 4400 more recursive calls. But HotSpot Server showed no significant
difference.
Without the nested try statements, JRockit not only behaved correctly,
but also out performed the HotSpot by 50000 more recursive calls. My guess
is that JRockit was not putting source code tracking information into the stack,
therefore was able to have a much larger stack. Can any one confirm this?