Статьи

Поймай StackOverFlowError за хвост

Одна из наиболее раздражающих ситуаций, с которыми вам, возможно, придется столкнуться при работе с Java-программой, — это StackOverFlowError. Если у вас хороший тестовый пример, то есть несколько вариантов, касающихся игры с размером стека или установки условной точки останова / след какой-то

Но если у вас есть тестовый случай, который может проваливаться один раз в 100 раз, возможно, состояние гонки в AWTMulticaster, как в моем случае, тогда вы хотите улучшить диагностику. Проблема в том, что по умолчанию виртуальная машина не будет отображать элементы в трассировке стека после первых 1024 записей. (По крайней мере, для JDK 6). Итак, если вы запустите следующий тривиальный пример:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
package other;
 
public class Overflow {
 
 
   public static final void call(double a, double b, double c, double d) {
       call(a,b,c,d);
   }
 
 
   public static void main(String[] args) {
       call(0,0,0,0);
   }
 
}

Вывод прекратится до того, как вы найдете причину проблемы, что затруднит решение проблемы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
> java other.Overflow
Exception in thread "main" java.lang.StackOverflowError
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
        [ lots of lines removed ]
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
Process exited with exit code 1.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
> java -XX:MaxJavaStackTraceDepth=1000000 other.Overflow
Exception in thread "main" java.lang.StackOverflowError
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
        [ lots of lines removed ]
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.main(Overflow.java:12)
Process exited with exit code 1.

Обратите внимание, что конец стека теперь содержит корень проблемы, который будет невероятно полезен при попытке диагностировать проблему.

Вы, вероятно, не хотите оставлять это свойство долгосрочным на производственных серверах, потому что я не совсем уверен в его влиянии. Глядя на код C ++, кажется, что это всего лишь максимальное значение и не повлияет на большинство других трассировок стека, поскольку они размещены в связанном списке в сегментах по 32 записи.

Ссылка: поймайте StackOverFlowError за хвост от нашего партнера по JCG