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

Отладка проблем с памятью Java: Анализ дампа потоков и кучи

В Java есть функция сборки мусора (GC), которая автоматически обрабатывает управление памятью для нас -… Помеченный как java, отладка.

В Java есть функция сборки мусора (GC), которая автоматически обрабатывает управление памятью для нас – определяет, какая память больше не используется приложением Java, уничтожает/освобождает неиспользуемые объекты и освобождает неиспользуемую память во время выполнения для повторного использования. Несмотря на то, что GC делает Java эффективным с точки зрения памяти, мы часто становимся жертвами катастрофических утечек памяти, которые непредсказуемым образом влияют на производительность программного обеспечения и могут даже вывести из строя всю систему.

Мониторинг активности GC JVM с использованием памяти и кучи и сбор дампов потоков/кучи, когда это необходимо, может помочь выявить и устранить распространенные проблемы с памятью Java. Обычно утечки памяти проявляются как OutOfMemoryError (ООМ), но не обязательно всегда. Например, если размер кучи слишком мал и если приложение пытается выделить память для новых объектов, но оно нарушило настроенный максимальный размер кучи, ошибка будет выглядеть следующим образом:

java.lang.OutOfMemoryError: Java heap space

Работа с дампами кучи Java

Java использует кучу в качестве хранилища для объектов Java. Сбор и анализ дампов кучи – отличный способ выявить и устранить многие проблемы, связанные с памятью.

Сбор Кучных Отвалов

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

Мы можем собирать дампы кучи для Java-приложения с помощью:

  1. Автоматически при ошибке OutOfMemoryError

    • Если в приложении Java настроен флаг виртуальной машины -XX:+HeapDumpOnOutOfMemoryError , затем при первой ошибке ООМ собирается дамп кучи. Обратите внимание, что никаких накладных расходов не будет, если только на самом деле не произойдет ООМ, поэтому рекомендуется включить это для всех производственных систем, что может быть удобно, если и когда возникнут какие-либо проблемы с памятью.
    • Важно отметить, что файл дампа может быть огромным, до гигабайт, поэтому убедитесь, что в целевой файловой системе достаточно места. Если приложение часто сталкивается с ошибкой OOM и часто создает дампы кучи, на диске может скоро закончиться свободное место, что приведет к еще большему количеству каскадных проблем!
  2. По запросу с помощью утилиты jmap (точка доступа OracleJDK/OpenJDK)

    • В каталоге Java bin вы можете использовать утилиту jmap , чтобы получить дамп кучи в реальном времени и/или сбросить кучу в OOM с аргументом JVM.
    • Найдите идентификатор процесса (PID) для приложения Java, выполнив ps aux | grep java .
    • Выполните приведенную ниже команду jmap , чтобы сгенерировать дамп кучи для данного процесса с PID с заданным .

Анализ Дампов кучи

Собранные дампы кучи не читаются напрямую. После сбора дампа кучи нам нужно будет проанализировать файл дампа кучи для анализа, чтобы получить читаемый и понятный отчет. Анализатор может помочь быстро рассчитать сохраненные размеры объектов, увидеть, кто/что мешает сборщику мусора собирать объекты, и определить подозреваемых в утечке памяти. Для этого доступно несколько инструментов анализатора – Eclipse MAT является одним из таких инструментов.

Использование Eclipse MAT

Eclipse Memory Analyzer (MAT) – это быстрый и многофункциональный анализатор кучи Java, который помогает вам находить утечки памяти и сокращать потребление памяти. Чтобы проанализировать дампы кучи (даже очень большие) с помощью Eclipse MAT, вы можете выполнить следующие действия:

  1. Установите JDK11 (или более новую версию)

    • Если у вас есть Homebrew и вы хотели бы установить Amazon Corretto (бесплатный дистрибутив OpenJDK), вы можете запустить brew tap homebrew/cask-versions && brew install --cask corretto .
    • Чтобы проверить установку, если она установлена на macOS, запустите /usr/libexec/java_home -V . При этом будет выведен путь к каталогу, в который установлен JDK.
  2. Установите Eclipse MAT

    • Установите Eclipse MAT следуя официальному руководству по установке
    • Предполагая, что Eclipse MAT установлен, и мы находимся внутри мат/ каталог, измените настройки файла MemoryAnalyzer.ini , чтобы использовать большую кучу для обработки больших дампов, и добавьте путь к папке Java bin в vm option.

  3. Запустите MAT против дампа кучи.

    Это занимает некоторое время для выполнения и генерирует файлы index и другие файлы, чтобы ускорить повторный анализ.

  4. Затем используйте файл index , созданный на предыдущем шаге, и запустите отчет “Подозреваемые в утечке” в дампе кучи. Это создаст небольшой выходной файл jvm_Leak_Suspects.zip который позволил бы легко просматривать HTML-отчет с подозрениями на утечку памяти.

Другие Альтернативные Инструменты Анализа Дампа Кучи

  • VisualVM : Инструмент профилирования/анализа Java с графическим интерфейсом, который можно использовать для профилирования производительности (включая анализ для каждого потока) , Сброс потоков/кучи, Мониторинг.

    • Для JDK 8 это поставляется в комплекте как jvisualvm . Для JDK 9 вам нужно будет загрузить его вручную.
  • JProfiler [Платно]: JProfiler – это профилировщик Java, объединяющий профилирование процессора, памяти и потоков в одном приложении.

Работа с дампами потоков

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

Сбор Дампов Потоков

Java JDK предоставляет несколько инструментов для захвата дампа потока Java-приложения, которые расположены в папке bin внутри домашнего каталога JDK. Одним из таких инструментов является jstack , который можно использовать, выполнив следующие действия:

  1. Найдите идентификатор процесса (PID) для приложения Java, выполнив ps aux | grep java .
  2. Запустите jstack с заданным PID и заданным именем файла (например, /tmp/thread_dump_1.txt ).

  3. Выходные данные, сохраненные в файле, представляют собой обычный текст и также могут быть просмотрены в простом текстовом редакторе.

Идентификация потоков, потребляющих много ЦП

  1. Захватите дамп потока Java-приложения, используя описанные выше шаги (если это еще не сделано).
  2. Найдите идентификатор процесса (PID) для приложения, выполнив ps aux | grep java .
  3. Определите идентификаторы потоков, потребляющих много ЦП, для заданного идентификатора процесса PID из предыдущего шага.

  4. Преобразуйте идентификатор потока в соответствующее шестнадцатеричное значение с помощью некоторого Преобразователя десятичных чисел в шестнадцатеричные .

  5. Найдите шестнадцатеричное значение ThreadId в выходном файле дампа потока, чтобы определить имя и трассировку стека нужного потока.

Отладка проблем со сборкой мусора

Журналы сбора мусора

Журналы сбора мусора могут записывать информацию об использовании памяти и показатели производительности, связанные со сбором мусора (пропускная способность, накопленные паузы, самая длинная пауза и т.д.). которые можно проанализировать с помощью таких инструментов, как GCViewer . Включение журналов GC в наших программных системах может пригодиться, когда что-то пойдет не так в случае таких проблем, как утечка памяти.

Ниже приведены некоторые распространенные флаги JVM, используемые для ведения журнала сборки мусора в Java 8. Обратитесь к https://www.baeldung.com/java-gc-logging-to-file для получения дополнительной информации.

"-XX:+PrintGCDetails"
"-XX:+PrintGCDateStamps"
"-XX:+PrintTenuringDistribution"
"-XX:+PrintClassHistogram"
"-Xloggc:gc_log_file.log"

Перекрестная рассылка по адресу https://sbvkrishna.tech/debugging-java-memory-issues

Рекомендации

  1. Сборка мусора Java
  2. Анализ hprof файла

Оригинал: “https://dev.to/sbvkrishna/debugging-java-memory-issues-thread-and-heap-dump-analysis-43c5”