How to finally block everytime run in jvm

Viewed 44
void tryCatchFinally() {
try {
    tryItOut();
} catch (TestExc e) {
    handleExc(e);
} finally {
    wrapItUp();
}


Method void tryCatchFinally()                                                                 
0   aload_0             // Beginning of try block
1   invokevirtual #4    // Method Example.tryItOut()V
4   goto 16             // Jump to finally block
7   astore_3            // Beginning of handler for TestExc;
                    // Store thrown value in local var 3
8   aload_0             // Push this
9   aload_3             // Push thrown value
10  invokevirtual #6    // Invoke handler method:
                    // Example.handleExc(LTestExc;)V
13  goto 16             // This goto is unnecessary, but was
                    // generated by javac in JDK 1.0.2
16  jsr 26              // Call finally block
19  return              // Return after handling TestExc
20  astore_1            // Beginning of handler for exceptions
                    // other than TestExc, or exceptions
                    // thrown while handling TestExc
21  jsr 26              // Call finally block
24  aload_1             // Push thrown value...
25  athrow              // ...and rethrow value to the invoker
26  astore_2            // Beginning of finally block
27  aload_0             // Push this
28  invokevirtual #5    // Method Example.wrapItUp()V
31  ret 2               // Return from finally block
Exception table:
From    To      Target      Type
0       4       7           Class TestExc
0       16      20          any

Hello comunity we have a method as we specified in the code above. And you see the bytecode output of this code below

My question is..if the tryItOut() method get a stackoverflow error. How Jvm go to finally block and return . we already dont have any memory. How does this process in jvm.

1 Answers

Let's say you've got 50 methods on the stack already and then call some recursive code like so:

try {
  recursiveCall();
} catch (StackOverflowError e) {
 ...
}

That recursive method goes some 40 levels deep and then SOErrs out.

That means all 40 methods end up being 'broken down' (each one of those 40 methods on the stack returns-by-way-of-throwable) and then it gets to your catch block. There's now about 40 methods worth of room on that stack to operate on, you'll be fine.

In the somewhat weird scenario where the stack is nearly full, and you invoke even 1 method, and that causes the SOErr, which you immediately catch, you're quite hampered; most things you'd try to do in that catch (StackOverflowError e) handler will themselves throw that exception, and a try/catch block does not apply to itself, so then that would just bubble up, breaking down methods as it goes, creating room.

finally is no different. You don't get to finally unless either [A] the try block finishes normally, or [B] it threw something, optionally got to some exception handler (which must also complete), and then it gets to your finally. In other words, if you get to a finally block because of StackOverflowError, what's the problem? A whole bunch of room is available now, that SOErr traveled up the stack, making room as it went.

Related