JVM имеет искусственное ограничение в 1024 записи, которые вы можете иметь в трассировке стека для исключения или ошибки, вероятно, для экономии памяти при ее возникновении (поскольку виртуальная машина должна выделять память для хранения трассировки стека).
К счастью, есть флаг, позволяющий увеличить этот лимит. Просто запустите свою программу со следующим аргументом:
-XX:MaxJavaStackTraceDepth=1000000
Это напечатает до 1 миллиона записей вашей трассировки стека, чего должно быть более чем достаточно. Также можно установить это значение на 0, чтобы установить неограниченное количество записей.
Этот список стандартные параметры JVM содержат более подробную информацию:
Максимум. нет. строк в трассировке стека для исключений Java (0 означает все). В Java > 1.6 значение 0 действительно означает 0. Для печати всего стека необходимо указать значение -1 или любое отрицательное число (проверено с 1.6.0_22, 1.7.0 в Windows). В Java ‹= 1.5 значение 0 означает все, JVM задыхается от отрицательного числа (проверено с 1.5.0_22 в Windows).
Запуск образца вопроса с этим флагом дает следующий результат:
Exception in thread "main" java.lang.StackOverflowError
at Overflow.<init>(Overflow.java:3)
at Overflow.<init>(Overflow.java:4)
at Overflow.<init>(Overflow.java:4)
at Overflow.<init>(Overflow.java:4)
(more than ten thousand lines later:)
at Overflow.<init>(Overflow.java:4)
at Overflow.<init>(Overflow.java:4)
at Overflow.a(Overflow.java:7)
at Overflow.main(Overflow.java:10)
Таким образом, вы можете найти первоначальных вызывающих код, вызвавший ошибку, даже если длина фактической трассировки стека превышает 1024 строки.
Если вы не можете использовать эту опцию, есть еще один способ, если вы находитесь в рекурсивной функции, подобной этой, и если вы можете ее изменить. Если вы добавите следующий try-catch:
public Overflow() {
try {
new Overflow();
}
catch(StackOverflowError e) {
StackTraceElement[] stackTrace = e.getStackTrace();
// if the stack trace length is at the limit , throw a new StackOverflowError, which will have one entry less in it.
if (stackTrace.length == 1024) {
throw new StackOverflowError();
}
throw e; // if it is small enough, just rethrow it.
}
}
По сути, это создаст и выдаст новый StackOverflowError, отбрасывая последнюю запись, потому что каждая будет отправлена на один уровень выше по сравнению с предыдущей (это может занять несколько секунд, потому что все эти ошибки должны быть созданы). Когда трассировка стека уменьшится до 1023 элементов, она просто перебрасывается.
В конечном итоге это напечатает 1023 строки в нижней части трассировки стека, что не является полной трассировкой стека, но, вероятно, является наиболее полезной ее частью.
person
Cyrille Ka
schedule
12.10.2013
Thread(ThreadGroup group, Runnable target, String name, long stackSize). - person bestsss   schedule 02.03.2011-Xss- это то, что тебе нужно, но обычно меня не интересуют однопоточные приложения, кроме некоторых микробенчмарков. - person bestsss   schedule 02.03.2011