Поиск запущенных экземпляров в работающей JVM

StackOverflow https://stackoverflow.com/questions/421422

  •  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).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top