java try-catch-finally рекурсивный вопрос - PullRequest
4 голосов
/ 19 июля 2011
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();
        }
    }
}

кто может объяснить вывод этого кода?

1.output в режиме клиента eclipse (бесконечный):


    try
    try
    ....


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

2.outout на сервере linux (сбой)режим:


    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)

1 Ответ

8 голосов
/ 19 июля 2011

Мне кажется, я помню это из книги "Java Puzzlers".Блок try выполняет неограниченную рекурсию, которая быстро приводит к возникновению ошибки StackOverflowError.Блоки try и catch возобновляют рекурсию, но с соответственно меньшим оставшимся стеком.Тем не менее, оставшийся стек снова становится больше, когда каждый рекурсивный вызов возвращает ...

Конечный результат - это граф вызовов, который формирует дерево с глубиной, зависящей от размера стека;при размере стека по умолчанию для основных JVM дерево становится настолько большим, что вам придется ждать много, много миллиардов лет, пока оно не будет полностью пройдено и программа не завершится.

Редактировать: Это то, что вы видите в режиме клиента: обход графа вызовов.То, что вы видите в Linux в режиме сервера, это либо ошибка JVM, либо аппаратный недостаток (неисправный ОЗУ может иметь такой эффект).

...