Вот мой пример приложения
public class Main {
private long[] exceptionLevels = new long[1000];
private int index;
public static void main(String... args) {
Main main = new Main();
try {
main.foo(0);
} finally {
Arrays.stream(main.exceptionLevels)
.filter(x -> x != 0)
.forEach(System.out::println);
}
}
private void foo(int level) {
try {
foo(level + 1);
} catch (StackOverflowError e) {
exceptionLevels[index++] = level;
bar(level + 1);
}
}
private void bar(int level) {
try {
bar(level + 1);
} catch (StackOverflowError e) {
exceptionLevels[index++] = -level;
}
}
}
Иногда, когда я запускаю приложение, я вижу результат, подобный этому
8074
8073
-8074
Что на самом деле означает, что произошло следующее
- foo (8073) вызывает foo (8074)
- foo (8074) вызывает foo (8075), который умирает
- foo (8074) регистрирует себя и вызывает панель (8075), котораяdies
- foo (8074) умирает и foo (8073) ловит его, регистрирует себя и вызывает bar (8074)
- bar (8074) вызывает bar (8075), который умирает, поэтому bar (8074)) регистрирует себя
- возвращаясь из всех методов, изящно завершает работу
Я понял, все в порядке.Таким образом, существует понятная схема получения
X, X-1, -X
для некоторого максимального уровня для вызовов X
Но иногда вызов Main дает такой вид вывода
6962
6961
-6963
что на самом деле
X, X-1, -(X+1)
Итак, вопрос в том, как?
PS Кроме того, когда я меняю все на статическое, программа полностью меняет свое поведение, так что даже иногда я получаю большечем 3 результата.
Редактировать: Когда я запускаю это с -Xss228k
, я всегда получаю
1281
1280
-1281
, но работа с -Xss1m
снова приводит меня к случайному размеру стека, а иногда и к случаюописано выше.