Поиск запущенных экземпляров в работающей JVM
-
05-07-2019 - |
Вопрос
Мне интересно, возможно ли получить дескриптор для запуска экземпляров данного класса. Особая проблема, которая вызвала это, была приложением, которое не выходит красиво из-за множества работающих потоков. Р>
Да, я знаю, что вы можете демонизировать theads, и они не будут задерживать выход из приложения. Но это заставило меня задуматься, возможно ли это. Самое близкое, что я могу, это загрузчики классов (защищенные!) ) "rel =" nofollow noreferrer "> findLoadedClass , хотя для этого вам потребуется запустить собственный загрузчик классов. Р>
Заметим ли это, как инструментам профилирования удается отслеживать дескрипторы объектов? запустив свои собственные загрузчики классов? или есть какой-то хороший хитрый способ, которого я не вижу? Р>
Решение
Вы действительно можете получить трассировку стека всех запущенных потоков, выгруженных в стандартный вывод, используя kill -QUIT <pid>
в * NIX-подобной ОС или запустив приложение в консоли Windows и нажав Ctrl-Pause
(как отмечает другой участник). ) р>
Однако кажется, что вы спрашиваете о программных способах сделать это. Итак, если вы действительно хотите, чтобы набор всех потоков, в которые текущие стеки вызовов включали один или несколько методов из данного класса ...
Лучшее, что я могу найти, не связанное с вызовами в JVMTI, - это проверить стеки всех запущенных потоков. Я не пробовал это, но это должно работать в Java 1.5 и позже. Имейте в виду, что это, по определению, не ВСЕ потокобезопасен (список запущенных потоков - и их текущие трассировки стека - будут постоянно меняться под вами ... много параноидальных вещей было бы необходимо для реального использования этого списка.)
public Set<Thread> findThreadsRunningClass(Class classToFindRunning) {
Set<Thread> runningThreads = new HashSet<Thread>();
String className = classToFindRunning.getName();
Map<Thread,StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
for(Thread t : stackTraces.keySey()) {
StackTraceElement[] steArray = stackTraces.get(t);
for(int i = 0;i<steArray.size();i++) {
StackTraceElement ste = steArray[i];
if(ste.getClassName().equals(className)) {
runningThreads.add(t);
continue;
}
}
}
return runningThreads;
}
Дайте мне знать, если этот подход сработает для вас!
Другие советы
Из эта страница ,
Профилировщик Java использует собственный интерфейс для JVM (JVMPI для Java < = 1.4.2 или JVMTI для Java & (= 1.5.0 ) для получения информации о профилировании из работающего приложения Java. Р>
Это составляет некоторый собственный код, предоставленный Sun это дает профилировщик зацепки в JVM.
Если вам нужна только быстрая трассировка стека вашего работающего приложения, чтобы выяснить, какие потоки блокируют выход JVM, вы можете отправить ему сигнал QUIT.
$ kill -QUIT <pid of java process>
В Windows вам нужно запустить приложение в окне консоли (используя java.exe
, а не javaw.exe
), затем вы можете нажать Ctrl-Pause, чтобы сгенерировать дамп стека. В обоих случаях он & # 8217; записывается на стандартный вывод.
Я использую Visual VM для мониторинга JVM. Имеет множество функций, попробуйте.
Я думаю, вам нужен дамп Java-потока . Это должно перечислить все темы с тем, что они делают в данный момент. У меня была похожая проблема, которую помог решить дамп потока (потоки планировщика Quartz, который не завершился после завершения работы Tomcat).