Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java try-catch-finally recursion question

public class Foo {

    public static void main(String[] args) {
        foo();
    }

    public static void foo() {
        try {
            System.out.println("try");
            foo();
        } catch (Throwable e) {
            System.out.println("catch");
            foo();
        } finally {
                System.out.println("finally");
                foo();
        }
    }
}

who can explain the output of this code ?

1.output on eclipse (endless) client mode:


    try
    try
    ....


    ...
    ...
    tryfinallyfinally
    tryfinallyfinally
    try
    try
    try
    tryfinallyfinally
    tryfinallyfinally
    try
    tryfinallyfinally
    tryfinallyfinally
    try
    ....
    ....

2.output on linux (crash) server mode:


    try
    try
    ...

    ...
    try
    try
    try
    try
    try
    try
    MISSING EXCEPTION HANDLER for pc 0x00002aaaab1c53f0 and handler bci -1
       Exception:

     Compiled exception table :
    ExceptionHandlerTable (size = 3304 bytes)
    catch_pco = 700 (1 entries)
      bci -1 at scope depth 0 -> pco 11039
    catch_pco = 1736 (1 entries)
      bci -1 at scope depth 0 -> pco 11473
    catch_pco = 1756 (1 entries)
      bci -1 at scope depth 0 -> pco 11433
    catch_pco = 1776 (1 entries)

like image 991
qkpk Avatar asked Feb 23 '23 13:02

qkpk


1 Answers

I think I remember this from the book "Java Puzzlers". The try block does an unbounded recursion which quickly results in a StackOverflowError being thrown. The try and catch blocks resume the recursion, but with a correspondingly smaller remaining stack. However, the the remaining stack gets larger again as each recursive call returns...

The end result is a call graph that forms a tree with the depth depending on the size of the stack; with the default stack size of mainstream JVMs the tree gets so large that you'd have to wait for many, many billions of years for it to be completely traversed and the program to terminate.

Edit: That's what you're seeing in client mode: the traversal of the call graph. What you're seeing on Linux in server mode is either a JVM bug or a hardware flaw (faulty RAM can have this effect).

like image 109
Michael Borgwardt Avatar answered Mar 06 '23 02:03

Michael Borgwardt