Рубрики
Без рубрики

Различные способы захвата Java-свалки

Узнайте несколько способов захвата свалки кучи на Java

Автор оригинала: Marcos Lopez Gonzalez.

1. Введение

В этой статье мы покажем различные способы захвата свалки кучи на Java.

Свалка кучи является моментальным снимком всех объектов, которые находятся в памяти в JVM в определенный момент . Они очень полезны для устранения проблем с утечкой памяти и оптимизации использования памяти в Java-приложениях.

Куча свалок, как правило, хранятся в файлах hprof двоичного формата. Мы можем открывать и анализировать эти файлы с помощью таких инструментов, как jhat или JVisualVM. Кроме того, для пользователей Eclipse очень часто используется MAT .

В следующих разделах мы пройдемся по нескольким инструментам и подходам для создания свалки кучи и покажем основные различия между ними.

2. Инструменты JDK

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

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

2.1. jmap

jmap является инструментом для печати статистики о памяти в запущенной JVM. Мы можем использовать его для локальных или удаленных процессов.

Чтобы захватить кучу свалки с помощью jmap мы должны использовать свалка выбор:

jmap -dump:[live],format=b,file= 

Наряду с этой опцией следует указать несколько параметров:

  • живые : Если установить его только печатает объекты, которые имеют активные ссылки и отбрасывает те, которые готовы к сбору мусора. Этот параметр является необязательным
  • формат’b : указывает, что файл дампа будет в двоичном формате. Если не установить результат, то тот же
  • файл : файл, в котором будет написана свалка
  • пид : идентификатор процесса Java

Примером может быть:

jmap -dump:live,format=b,file=/tmp/dump.hprof 12587

Помните, что мы можем легко получить пид Java-процесса с помощью JPS команда.

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

2.2. jcmd

jcmd является очень полным инструментом, который работает, отправив командные запросы на JVM. Мы должны использовать его в той же машине, где работает процесс Java.

Одной из его многочисленных команд является GC.heap_dump . Мы можем использовать его, чтобы получить кучу свалки, просто указав пид процесса и пути вывода файла:

jcmd  GC.heap_dump 

Мы можем выполнить его с теми же параметрами, которые мы использовали раньше:

jcmd 12587 GC.heap_dump /tmp/dump.hprof

Как и в случае с jmap, сгенерированная свалка находится в двоичном формате.

2.3. JVisualVM

JVisualVM является инструментом с графическим пользовательским интерфейсом, который позволяет нам контролировать, устранение неполадок и профили Java приложений . Графический интерфейс прост, но очень интуитивно понятен и прост в использовании.

Один из его многочисленных вариантов позволяет нам захватить кучу свалки. Если мы нажимаем правой кнопкой мыши на процесс Java и выбираем “Свалка” опция, инструмент создаст кучу свалки и открыть его в новой вкладке:

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

Начиная с JDK 9, Visual VM не входит в дистрибутивы Oracle JDK и Open JDK. Поэтому, если мы используем Java 9 или более новые версии, мы можем получить JVisualVM от Visual VM с открытым исходным кодом сайт проекта .

3. Захват свалки кучи автоматически

Все инструменты, которые мы показали в предыдущих разделах, предназначены для захвата кучи свалок вручную в определенное время. В некоторых случаях, мы хотим получить кучу свалки, когда java.lang.OutOfMemoryError происходит так, что это помогает нам исследовать ошибку.

В этих случаях Java предоставляет HeapDumpOnOutOfMemoryError опция командной строки, генерируемая свалкой кучи при java.lang.OutOfMemoryError брошен:

java -XX:+HeapDumpOnOutOfMemoryError

По умолчанию он хранит свалку в java_pid.hprof файл в каталоге, где мы запускаем приложение. Если мы хотим указать другой файл или каталог, мы можем установить его в ХипДемпПат выбор:

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=

Когда у нашего приложения заканчивается память с помощью этой опции, мы сможем увидеть в журналах созданный файл, содержащий свалку кучи:

java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Dumping heap to java_pid12587.hprof ...
Exception in thread "main" Heap dump file created [4744371 bytes in 0.029 secs]
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at com.baeldung.heapdump.App.main(App.java:7)

В приведеном выше примере она была написана java_pid12587.hprof файл.

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

Наконец, эта опция также может быть указана во время выполнения с помощью HotSpotДиагностик МБин . Для этого мы можем использовать JConsole и установить HeapDumpOnOutOfMemoryError Вариант VM для истинное :

Мы можем найти более подробную информацию о MBeans и JMX в этой статье .

4. JMX

Последний подход, который мы будем охватывать в этой статье является использование JMX. Мы будем использовать HotSpotДиагностик МБин что мы кратко представили в предыдущем разделе. Этот MBean обеспечивает свалкаХап метод который принимает 2 параметра:

  • выходFile : путь файла для свалки. Файл должен иметь расширение hprof
  • живые : если установлен на самом деле он сбрасывает только активные объекты в памяти, как мы видели с jmap раньше

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

4.1. JConsole

Самый простой способ использовать HotSpotДиагностик MBean с помощью JMX клиента, таких как JConsole.

Если мы откроем JConsole и подключиться к запущенной Java-процессу, мы можем перейти к MBeans вкладке и найти HotSpotДиагностик под com.sun.management . В операциях мы можем найти свалкаХап метод, который мы описали ранее:

Как показано, нам просто нужно ввести параметры выходFile и живые в p0 и p1 текстовые поля для выполнения свалкаХап операция.

4.2. Программный путь

Другой способ использования HotSpotДиагностик MBean, ссылаясь на него программно из Java-кода.

Для этого нам сначала нужно получить MBeanServer например, для того, чтобы получить MBean, который зарегистрирован в заявке. После этого нам просто нужно получить экземпляр HotSpotDiagnosticMXBean и назвать его свалкаХап метод .

Давайте посмотрим его в коде:

public static void dumpHeap(String filePath, boolean live) throws IOException {
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
      server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
    mxBean.dumpHeap(filePath, live);
}

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

Exception in thread "main" java.io.IOException: File exists
	at sun.management.HotSpotDiagnostic.dumpHeap0(Native Method)
	at sun.management.HotSpotDiagnostic.dumpHeap(HotSpotDiagnostic.java:60)

5. Заключение

В этом учебнике мы показали несколько способов захвата свалки кучи на Java.

Как правило, мы должны помнить, чтобы использовать HeapDumpOnOutOfMemoryError опция всегда при запуске Java-приложений. Для других целей, любой из других инструментов может быть прекрасно использован до тех пор, как мы держим в виду неподдерживаемый статус jmap.

Как всегда, полный исходный код примеров доступен более на GitHub .