Вопрос

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

Что мне нужно, так это возможность отслеживать методы, которые вызывает программа, и какие методы вызываются внутри этого метода, и так далее.Очевидно, что трассировки стека обеспечивают именно эту функциональность:

 java.lang.NullPointerException
     at MyClass.mash(MyClass.java:9)
     at MyClass.crunch(MyClass.java:6)
     at MyClass.main(MyClass.java:3)

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

Теперь я, конечно, подумал о том, чтобы просто изменить поток печати системного класса, чтобы поток печатал свой стек в мой PrintStream, но это кажется каким-то неправильным.

Есть ли лучший способ сделать это?Есть ли какие-либо уже существующие классы / методы, которые я могу использовать?

Кроме того, в настоящее время я загружаю исходный код Java, чтобы проверить, как именно класс thread печатает свой стек, поэтому я мог бы, возможно, создать подкласс thread и имитировать метод dumpStack() своим собственным методом getStack().

Это было полезно?

Решение 2

Ой, просматривая исходный код, я заметил, что у класса потока есть метод public StackTraceElement [] getStackTrace (), его просто нет в документации, которую я читал. Теперь я чувствую себя глупо.

Так что да, похоже, это решение.

Другие советы

Посмотрите также на VisualVM, поставляемый с последними выпусками Java.

Одним из подходов может быть использование чего-то вроде BCEL для предварительной обработки целевого байт-кода для вставки вызовов в ваш собственный код при каждом входе и выходе метода (вероятно, лучше всего выполнить выход, обернув весь метод в блок try / finally, чтобы перехватить исключения при выходе). Отсюда вы можете вывести дерево вызовов именно так, как оно происходит.

Для этого вы можете использовать AspectJ . Ознакомьтесь с описанием , которое точно ваш вариант использования.

Взгляните на ThreadMXBean ( многопоточный ) класс - это то, что вам нужно.По сути, вы:

  • вызовите ManagementFactory.getThreadMXBean(), чтобы получить экземпляр ThreadMXBean;
  • вызовите getAllThreadIds() в результирующем ThreadMXBean для перечисления текущих потоков;
  • вызовите getThreadInfo(), чтобы получить n верхних элементов трассировки стека из заданного списка потоков.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top