Инструмент для анализа больших дампов Java-кучи
У меня есть дамп кучи HotSpot JVM, который я хотел бы проанализировать. ВМ побежал с -Xmx31g
и размер файла дампа кучи составляет 48 ГБ.
- Я даже не буду пытаться
jhat
, так как он требует примерно в пять раз больше кучи памяти (в моем случае это будет 240 ГБ) и работает очень медленно. - Eclipse MAT вылетает с
ArrayIndexOutOfBoundsException
после анализа кучи дамп в течение нескольких часов.
Какие другие инструменты доступны для этой задачи? Лучше всего использовать набор инструментов командной строки, состоящий из одной программы, которая преобразует дамп кучи в эффективные структуры данных для анализа, в сочетании с несколькими другими инструментами, которые работают с предварительно структурированными данными.
12 ответов
Обычно я использую ParseHeapDump.sh
включен в Eclipse Memory Analyzer и описан здесь, и я делаю это на одном из наших более продвинутых серверов (загрузите и скопируйте с дистрибутива linux .zip, распакуйте там). Сценарию оболочки требуется меньше ресурсов, чем анализировать кучу из графического интерфейса, плюс вы можете запустить его на своем мощном сервере с большим количеством ресурсов (вы можете выделить больше ресурсов, добавив что-то вроде -vmargs -Xmx40g -XX:-UseGCOverheadLimit
до конца последней строки сценария. Например, последняя строка этого файла может выглядеть так после изменения
./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit
Запустить как ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof
После этого он создает ряд "индексных" файлов рядом с файлом.hprof.
После создания индексов я пытаюсь сгенерировать отчеты по ним и просмотреть эти отчеты на своих локальных компьютерах и попытаться выяснить, смогу ли я найти виновного именно по этому (не только отчеты, но не индексы). Вот учебник по созданию отчетов.
Пример отчета:
./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects
Другие параметры отчета:
org.eclipse.mat.api:overview
а также org.eclipse.mat.api:top_components
Если этих отчетов недостаточно, и если мне нужно больше копать (например, через oql), я копирую индексы, а также файл hprof на свою локальную машину, а затем открываю дамп кучи (с индексами в том же каталоге, что и свалка) с моим Eclipse MAT GUI. Оттуда ему не нужно слишком много памяти для запуска.
РЕДАКТИРОВАТЬ: Мне просто понравилось добавить две заметки:
- Насколько я знаю, только генерация индексов является частью Eclipse MAT, интенсивно использующей память. После того, как у вас есть индексы, большая часть вашей обработки в Eclipse MAT не будет нуждаться в таком большом количестве памяти.
- Выполнение этого с помощью сценария оболочки означает, что я могу сделать это на безголовом сервере (и обычно я делаю это также на безголовом сервере, потому что они обычно самые мощные). И если у вас есть сервер, который может генерировать дамп кучи такого размера, скорее всего, у вас есть еще один сервер, который также может обрабатывать большую часть кучи дампов.
В случае использования MAT на MAC (OSX) у вас будет файл MemoryAnalyzer.ini в MemoryAnalyzer.app/Contents/MacOS. Это не сработало для меня. Вы можете создать измененную команду запуска / сценарий оболочки на основе содержимого этого файла и запустить его из этого каталога. В моем случае я хотел 20 ГБ кучи:
./MemoryAnalyzer -startup ../../../plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar --launcher.library ../../../plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.300.v20150602-1417 -vmargs -Xmx20g --XX:-UseGCOverheadLimit -Dorg.eclipse.swt.internal.carbon.smallFonts -XstartOnFirstThread
Просто запустите эту команду / скрипт из каталога Contents / MacOS через терминал, чтобы запустить графический интерфейс с большей доступной оперативной памятью.
Принятый ответ на этот связанный с этим вопрос должен послужить хорошим началом для вас (использует живые гистограммы jmap вместо дампов кучи):
Метод обнаружения утечки памяти в больших дампах Java-кучи
Большинству других анализаторов кучи (я использую IBM http://www.alphaworks.ibm.com/tech/heapanalyzer) требуется как минимум на процент ОЗУ больше, чем кучи, если вы ожидаете хороший инструмент с графическим интерфейсом.
Помимо этого, многие разработчики используют альтернативные подходы, такие как анализ стеков в реальном времени, чтобы понять, что происходит.
Хотя я должен спросить, почему ваши кучи такие большие? Влияние на распределение и сборку мусора должно быть огромным. Держу пари, что большой процент того, что у вас в куче, должно храниться в базе данных / постоянном кэше и т. Д. И т. Д.
Я предлагаю попробовать YourKit. Обычно ему требуется немного меньше памяти, чем размер дампа кучи (он индексирует его и использует эту информацию для получения того, что вы хотите)
Еще несколько вариантов:
Этот человек http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html
написал собственный анализатор кучи NetBeans, который просто предоставляет интерфейс "стиля запроса" через файл дампа кучи вместо фактической загрузки файла в память.
https://github.com/aragozin/jvm-tools/tree/master/hprof-heap
Хотя я не знаю, лучше ли его язык запросов, чем OQL Eclipse, упомянутый в принятом ответе.
Говорят также, что JProfiler 8.1 ($499 за пользовательскую лицензию) способен обходить большие кучи без больших затрат.
Последняя сборка моментальных снимков Eclipse Memory Analyzer имеет возможность случайным образом отбрасывать определенный процент объектов, чтобы уменьшить потребление памяти и позволить анализировать оставшиеся объекты. См. Ошибку 563960 и сборку ночных снимков, чтобы протестировать эту возможность перед включением в следующий выпуск MAT.
Не очень известный инструмент - http://dr-brenschede.de/bheapsampler/ хорошо работает для больших куч. Он работает путем выборки, поэтому ему не нужно читать всю вещь, хотя и немного привередливо.
Это не решение командной строки, однако мне нравятся инструменты:
Скопируйте дамп кучи на сервер, достаточно большой для его размещения. Вполне возможно, что оригинальный сервер может быть использован.
Войдите на сервер через ssh -X
запустить графический инструмент удаленно и использовать jvisualvm
из двоичного каталога Java для загрузки .hprof
файл дампа кучи.
Инструмент не загружает полный дамп кучи сразу в память, но загружает детали, когда они необходимы. Конечно, если вы посмотрите в файл достаточно, требуемая память в конечном итоге достигнет размера дампа кучи.
Когда проблему можно «легко» воспроизвести, одной из неупомянутых альтернатив является создание дампов кучи до того, как память станет такой большой ( например ,
jmap -dump:format=b,file=heap.bin <pid>
).
Во многих случаях вы уже получите представление о том, что происходит, не дожидаясь OOM.
Кроме того, MAT предоставляет функцию сравнения разных снимков, которая может пригодиться (см. /questions/6211314/java-ispolzovanie-memory-analyzer-tool-mat-sravnenie-dvuh-heapdump/49456206#49456206 для получения инструкций и описания).
Идея состоит в том, чтобы использовать опцию headless MAT, поскольку в системе Windows с ограниченной оперативной памятью вы не можете анализировать большие файлы дампа кучи.
Загрузите последнюю версию мата для unix env - например. MemoryAnalyzer-1.14.0.20230315-linux.gtk.x86_64.ziphttps://www.eclipse.org/mat/downloads.php и распакуйте в любой каталог вашего сервера.
Обновите конфигурацию MAT, присутствующую в /MAT-folder-path/MemoryAnalyzer.ini:
Для инструмента MAT требуется минимум jdk-17, установите путь JVM (версия > java-17)
Увеличьте объем памяти кучи, например -Xmx16384m, в соответствии с размером дампа кучи.
-vm /path-to/jdk-17/bin -vmargs -Xmx16384m
Полезно иметь служебный сценарий для создания отчетов из файла дампа кучи — heapAnaанализ.sh (сохраняйте свободное место на диске в два раза больше размера дампа кучи)
#!/bin/sh heapFilePath="$1"; if [[ -z $heapFilePath ]]; then echo "The heapFilePath received : $heapFilePath"; if [ -f $heapFilePath ]; then # MAT folder path : - ParseHeapDump.sh script matDirectory="/MAT-folder-path/mat" matScript="ParseHeapDump.sh" heapDumpParserScript=$matDirectory/$matScript # To parse the heap dump file and generate the html report in zip format. echo "[1] Leak suspect report analysis started.."; $heapDumpParserScript $heapFilePath org.eclipse.mat.api:suspects echo "Analysis completed : Leak suspect report."; # You can comment out below [2] and [3] blocks. Usually LeakSuspect report helps in 80% of cases. echo "[2] System overview report analysis started.."; $heapDumpParserScript $heapFilePath org.eclipse.mat.api:overview echo "Analysis completed : System overview report."; echo" [3] Top Component report analysis started.."; $heapDumpParserScript $heapFilePath org.eclipse.mat.api:top_components echo "Analysis completed : Top Component report."; else echo "Provide the correct filepath of heap dump, $heapFilePath file doesn't exist."; fi else echo "Provide the mandatory argument of the script."; fi
Выполнить скрипт для анализа дампа кучи. (Используйте утилиту экрана, чтобы отключить сеанс в терминале Unix, чтобы избежать прерывания процесса. Поскольку такой анализ занимает часы.)
source /script/heapAnalysis.sh /path-to/heapDumpFile.hprof
Теперь вы можете загрузить отчет в формате html (размером около нескольких МБ) в свою локальную систему с помощью инструмента WinSCP. Если вы хотите, вы можете перенести индексированные файлы (ParseHeapDump.sh создает индексированные файлы) в систему Windows и загрузить их с помощью MAT.
Я наткнулся на интересный инструмент под названием JXray. Он предоставляет ограниченную пробную лицензию. Было очень полезно найти утечки памяти. Вы можете дать ему шанс.
Попробуйте использовать jprofiler, он хорошо работает при анализе больших.hprof, я пробовал с размером файла около 22 ГБ.
https://www.ej-technologies.com/products/jprofiler/overview.html