Получите обнаружение взаимоблокировок из запущенной программы или дампа на Java

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

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

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

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

Любые идеи?


person Franz Kafka    schedule 14.11.2011    source источник
comment
Можете ли вы включить удаленную отладку в следующий раз? т.е. stackoverflow.com/questions/138511/   -  person laher    schedule 14.11.2011


Ответы (3)


На самом деле вы можете попробовать использовать visualvm + его плагин мониторинга потоков. Вы также сможете делать дамп потока, просматривать следы стека потоков и их состояние. Вы также можете использовать jconsole для обнаружения тупиковых ситуаций. Оба инструмента являются частью JDK. JConsole

Здесь есть дополнительная информация об использовании visualvm для анализа потоков. .

person szhem    schedule 14.11.2011

Можете взять с него дамп-нить. Вы можете использовать kill -3 PID, где PID - это идентификатор вашего процесса. Это приведет к тому, что дамп потока будет выводиться на стандартный вывод вашей программы.

Это покажет вам, что делает каждый поток, но не даст вам никакой информации о переменных. Тем не менее, дампы потоков действительно полезны. Я бы начал там. Если вы все еще не можете решить проблему, вы можете использовать что-то вроде jmap (инструмент JVM, бесплатный, но сложный в использовании) или YourKit (платный, но очень хороший продукт), чтобы сделать снимок памяти и изучить переменные.

Некоторая информация о jmap: Java профилирование памяти с помощью jmap и jhat

person Andres Olarte    schedule 14.11.2011
comment
kill -3 PID, похоже, ничего не делает. После этого JVM все еще жива. Как это может быть? - person Franz Kafka; 15.11.2011
comment
kill -3 на самом деле не убивает JVM, он просто отправляет сигнал для запуска дампа потока. Дамп потока поступает на стандартный вывод JVM (а не на стандартный вывод команды kill). Просто убедитесь, что вы записываете стандартный вывод в файл. Как вы выполняете свою программу? Это отдельное приложение или вы работаете на сервере приложений, таком как Tomcat? Если, например, вы используете Tomcat, вывод std находится в logs / catalina.out. В автономном режиме вы можете направить свой стандартный вывод в какой-либо файл, запустив приложение примерно так: java -jar myjar.jar ›output.log. Надеюсь это поможет. - person Andres Olarte; 15.11.2011
comment
Что если в вашем автономном случае вы не можете повторно запустить приложение, потому что оно производственное и уже запущено, как вы можете направить дамп потока в файл? - person J.E.Y; 30.09.2019

На последних JVM (OpenJDK / Oracle Java 7 или выше), если вы берете дамп кучи (используя VisualVM или jmap), он также включает дамп стеков всех запущенных в данный момент потоков со ссылками на соответствующие объекты в куче. . Затем вы можете просмотреть стеки, открыв дамп кучи в VisualVM.

person James_pic    schedule 04.07.2017