Как расширить размер трассировки стека 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 будет печатать каждый уровень, который был записан. Ваша проблема в том, что стек слишком глубок для того, что он помещает в трассировку стека.

Можете ли вы попробовать уменьшить размер стека?

Если у вас есть доступ к вызову до того, как он войдет в предполагаемое переполнение стека, вы можете просто сгенерировать дополнительную трассировку стека, например new Exception().getStackTrace, Обратите внимание, что foldRight само по себе не приведет к бесконечной рекурсии. Возможно, вам просто не хватает памяти, попробуйте увеличить размер стека JVM.

Другие вопросы по тегам