Как получить стек вызовов Java запущенного приложения

Я работаю над очень огромным веб-приложением java. Поскольку нет правильного ведения журнала во время разработки, поэтому мне очень сложно поставить точку останова и отладить приложение, поскольку я не знаю порядка выполнения. Есть ли какой-либо механизм для получения полного стека вызовов запущенного приложения java после выполнения некоторых действий.

Я долго искал его в сети, но не могу прийти к конкретному решению. Пожалуйста, предложите мне, если что-то есть для этого. Спасибо

6 ответов


метод 1: используйте утилиту jstack из командной строки (часть дистрибутива JDK).

Метод 2: отправьте Сигнал 3 в процесс java, он сбросит следы стека на stdout.

Метод 3: Вызов Потока.getAllStackTraces () из приложения:

public class StackTraceDumper
{
    public static dumpAllStackTraces ()
    {
        for (Map.Entry <Thread, StackTraceElement []> entry: 
            Thread.getAllStackTraces().entrySet ())
        {
            System.out.println (entry.getKey ().getName () + ":");
            for (StackTraceElement element: entry.getValue ())
                System.out.println ("\t" + element);
        }
    }
}

затем использовать StackTraceDumper.dumpAllStackTraces() где вам нужно сбросить трассировки стека.


Thread.dumpStack() Печать трассировки стека текущего потока в стандартный поток ошибок. Thread.getAllStackTraces() Возвращает карту трассировок стека для всех живых потоков. Thread.getStackTrace() Возвращает массив элементов трассировки стека, представляющих дамп стека этого потока.


посмотреть Throwable.getStackTrace(). Просто создайте новый Throwable; на самом деле вам не нужно throw его.


вы можете вызвать дамп стека, нажав Ctrl + Break, или отправка сигнала 3 (в системах на базе Unix). Обратите внимание, что вы получите трассировку стека в потоке. Это пойдет на Стандартная ошибка, поэтому убедитесь, что ваш журнал захватывает это.

вы можете сделать это программно через

Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();

здесь подробнее о получении и анализе следов стека.

Как вы заметили, BTrace является другим возможность. Вот!--16-->и ответ по его использованию.


есть несколько вариантов:

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

добавить некоторые основные ведения журнала в код:

new RuntimeException().printStackTrace();

это приведет к статической трассировке stderr


Почему бы вам не использовать какой-нибудь инструмент AOP, такой как AspectJ, чтобы захватить эти значения и войти? Вы можете использовать execution() point cut вместе с Советом after (). Для непроизводственного развертывания можно регистрировать все вызовы метода вместе с переданными значениями и возвращенным значением. Это будет слишком много накладных расходов для производства ОКР. Для этого вы можете просто хранить переданные значения (Object args[] как вы получаете в AspectJ advice) в локальной переменной и регистрировать его только в случае исключения. Но даже в этом случае будут некоторые штраф за производительность в качестве примитивных значений будет помещен в поле для передачи в качестве объекта[] вашему совету.