Как получить поток и дамп кучи Java-процесса в Windows, который не работает в консоли - PullRequest
218 голосов
/ 02 января 2009

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

В Unix я мог сделать kill -3 <pid>, но в Windows AFAIK единственный способ получить дамп потока - это Ctrl-Break в консоли. Но это только дает мне дамп родительского процесса, а не дочернего.

Есть ли другой способ получить этот дамп кучи?

Ответы [ 18 ]

357 голосов
/ 15 июня 2010

Вы можете использовать jmap, чтобы получить дамп любого запущенного процесса, предполагая, что вы знаете pid.

Используйте диспетчер задач или монитор ресурсов, чтобы получить pid. Тогда

jmap -dump:format=b,file=cheap.bin <pid>

чтобы получить кучу для этого процесса.

110 голосов
/ 18 сентября 2013

Вы путаете два разных дампов Java. kill -3 создает дамп потока, а не дамп кучи.

Дамп потока = трассировка стека для каждого потока в выводе JVM в стандартный вывод в виде текста.

Дамп кучи = содержимое памяти для вывода процесса JVM в двоичный файл.

Чтобы получить дамп потока в Windows, CTRL + BREAK , если ваша JVM является процессом переднего плана, является самым простым способом. Если у вас есть Unix-подобная оболочка в Windows, такая как Cygwin или MobaXterm, вы можете использовать kill -3 {pid}, как в Unix.

Чтобы получить дамп потока в Unix, CTRL + C , если ваша JVM является процессом переднего плана или kill -3 {pid} будет работать до тех пор, пока вы получите правильный PID для JVM .

В любой платформе Java поставляется с несколькими утилитами, которые могут помочь. Для дампов потоков jstack {pid} - ваш лучший выбор. http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.html

Просто чтобы закончить вопрос о дампе: дампы кучи обычно не используются, потому что их трудно интерпретировать. Но они содержат много полезной информации, если вы знаете, где и как на них смотреть. Наиболее распространенное использование - обнаружение утечек памяти. Рекомендуется установить -D в командной строке java, чтобы дамп кучи автоматически генерировался при ошибке OutOfMemoryError, -XX:+HeapDumpOnOutOfMemoryError Но вы также можете вручную запустить дамп кучи. Наиболее распространенный способ - использовать утилиту java jmap.

ПРИМЕЧАНИЕ: эта утилита доступна не на всех платформах. Начиная с JDK 1.6, jmap доступно в Windows.

Пример командной строки будет выглядеть примерно так:

jmap -dump:file=myheap.bin {pid of the JVM}

Вывод «myheap.bin» не читается человеком (для большинства из нас), и вам понадобится инструмент для его анализа. Я предпочитаю MAT. http://www.eclipse.org/mat/

30 голосов
/ 15 октября 2013

Я думаю, что лучший способ создать файл .hprof в процессе Linux - это команда jmap . Например: jmap -dump:format=b,file=filename.hprof {PID}

18 голосов
/ 29 ноября 2009

В дополнение к использованию упомянутого jconsole / visualvm вы можете использовать jstack -l <vm-id> в другом окне командной строки и записать этот вывод.

можно найти с помощью диспетчера задач (это идентификатор процесса в Windows и Unix) или с помощью jps.

И jstack, и jps включены в Sun JDK версии 6 и выше.

16 голосов
/ 02 января 2009

Я рекомендую Java VisualVM, распространяемый с JDK (jvisualvm.exe). Он может подключаться динамически и получать доступ к потокам и куче. Я нашел в неоценимых для некоторых проблем.

14 голосов
/ 08 июля 2016

Попробуйте один из следующих вариантов.

  1. Для 32-битной JVM:

    jmap -dump:format=b,file=<heap_dump_filename> <pid>
    
  2. Для 64-битной JVM (с явным цитированием):

    jmap -J-d64 -dump:format=b,file=<heap_dump_filename> <pid>
    
  3. Для 64-битной JVM с алгоритмом G1GC в параметрах ВМ (с помощью алгоритма G1GC генерируется только куча живых объектов):

    jmap -J-d64 -dump:live,format=b,file=<heap_dump_filename> <pid>
    

Связанный вопрос SE: Ошибка дампа кучи Java с помощью команды jmap: Преждевременный EOF

Посмотрите на различные варианты jmap в этой статье

13 голосов
/ 09 февраля 2016

Если вы используете server-jre 8 и выше, вы можете использовать это:

jcmd PID GC.heap_dump /tmp/dump
12 голосов
/ 18 января 2012

Если вы хотите, чтобы в режиме нехватки памяти находилась куча, вы можете запустить Java с параметром -XX:-HeapDumpOnOutOfMemoryError

c.f. Справочная страница параметров JVM

6 голосов
/ 02 января 2009

Вы можете запустить jconsole (входит в состав Java 6 SDK) и подключиться к вашему Java-приложению. Он покажет вам каждый запущенный поток и его трассировку стека.

5 голосов
/ 02 января 2009

Вы можете отправить kill -3 <pid> от Cygwin. Вы должны использовать опции Cygwin ps, чтобы найти процессы Windows, а затем просто отправить сигнал этому процессу.

...