Как расширить размер трассировки стека Java, чтобы увидеть дно стека? (вызывая переполнение стека)
Есть ли в Java какой-либо способ просмотреть полную, не усеченную трассировку стека (например, путем увеличения количества записанных кадров) или иным образом получить в нижней части трассировки стека? Обычно трассировка стека усекается сверху с 1024 кадрами, но для проблемы переполнения стека это довольно бесполезно, так как вам действительно нужно увидеть, кто сделал вызов, вызвавший рекурсию, внизу у дна. Намного лучше было бы усечение в середине стека, но, очевидно, JVM от Sun недостаточно умна, чтобы делать это.
Возможно, даже какие-то особые специфичные для Солнца флаги Я попытался уменьшить размер стека до минимально допустимого (-Xss1000), но это все еще стоит более 1024 кадров.
В моем случае я пытаюсь отладить переполнение стека, которое происходит в преобразователе Hadoop, но только при работе с действительно большим вводом. Я предполагаю, что проблема возникает из-за рекурсивной операции (Scala's foldRight
) делается в действительно очень большом связанном списке, и мне нужно переписать его не рекурсивно... но мне нужно знать, кто звонил foldRight
, Это базовая процедура, вызываемая прямо и косвенно во многих местах, и есть много-много кода, с которым я работаю, так что это совершенно неочевидно.
4 ответа
Попробуйте -XX:MaxJavaStackTraceDepth
Вариант 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).
Вы можете перебирать трассировку стека самостоятельно
Throwable t =
for(StackTraceElement ste: t.getStackTrace()) {
// is it a repeat??
}
По умолчанию printStackTrace будет печатать каждый уровень, который был записан. Ваша проблема в том, что стек слишком глубок для того, что он помещает в трассировку стека.
Можете ли вы попробовать уменьшить размер стека?
Попробуйте использовать jstack:
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstack.html
http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/tooldescr.html
Если у вас есть доступ к вызову до того, как он войдет в предполагаемое переполнение стека, вы можете просто сгенерировать дополнительную трассировку стека, например new Exception().getStackTrace
, Обратите внимание, что foldRight
само по себе не приведет к бесконечной рекурсии. Возможно, вам просто не хватает памяти, попробуйте увеличить размер стека JVM.