Мониторинг приложений Java (6) — сторонний инструмент анализа памяти MAT

Java

tags: java,troubleshooting,monitor,mat


Вкратце в одном предложении:MATЭто мощный инструмент анализа памяти, который может быстро и эффективно помочь нам найти утечку памяти и уменьшить потребление памяти, инструменты анализа, которые будут объяснены ниже.

1. Введение

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

  • Добавьте параметры запуска для автоматического дампа при возникновении OOM: Параметры запуска java-приложений обычно лучше всего добавить-XX:+HeapDumpOnOutOfMemoryErrorи-XX:HeapDumpPath=logs/heapdump.hprof, т. е. автоматически сбрасывать моментальные снимки кучи, когда происходит OOM, но этот подход довольно медленный (необходимо подождать до окончания OOM).
  • Делайте дамп вручную по запросу с помощью команды: Мы также можем использоватьjmap -dump:format=b,file=HeapDump.hprof <pid>Инструменты для ручного создания дампов кучи и дампов потоков
  • Ручной дамп с помощью инструмента: какпредыдущий постправильноjconsoleиjvisualvmКак упоминалось в объяснении, jvisualvm имеет функцию предоставления моментальных снимков кучи дампа, просто нажмите.

Итак, как анализировать сброшенные файлы?jvisualvmФайлы моментальных снимков могут быть загружены непосредственно для анализа, в то время какMAT, условно говоря, функция анализа памяти является более мощной, она может автоматически определять места, где могут возникнуть проблемы (особенно переполнение памяти, утечка памяти), а также может проверять использование памяти классом, вызов уровня метода и т. д. в деталь Редкий инструмент для ситуации.

2 Введение в инструменты MAT

MAT (Memory Analyzer tool) — это инструмент для анализа памяти, который представляет собой быстрый и многофункциональный анализатор кучи памяти, который помогает нам находить утечки памяти и анализировать проблемы с высоким потреблением памяти.Официальный сайтДа:https://www.eclipse.org/mat/, можете посмотреть, если интересно. Используя MAT, можно легко реализовать следующие функции:

  • найти самый большой объект, так как MAT обеспечивает разумный совокупный размер для отображения (retained size)
  • Исследуйте графы объектов, в том числеinboundиoutboundСсылки, то есть то, что ссылается на этот объект и что этот объект вызывает.
  • Находит объекты, которые нельзя восстановить, может вычислить путь от корня сборщика мусора до связанных объектов
  • Найдите пустую память, такую ​​как избыточные объекты String, пустые объекты коллекции и т. д.

3 Установка инструмента MAT

MATЕсть два способа установки, один из нихeclipseУстановка плагина, одна из них - независимая установка. существуетMATизофициальная документацияЕсть соответствующие установочные файлы для загрузки, адрес загрузки:https://www.eclipse.org/mat/downloads.php

  • Если он установлен с помощью плагина eclipse,help -> install new softнажмитеADDи добавьте адрес плагина во всплывающее окно:http://download.eclipse.org/mat/1.9.0/update-site/, вы также можете загрузить пакет подключаемого модуля для автономной работы непосредственно на странице загрузки и установить его в автономном режиме.
  • Самостоятельная установка, под Windows, скачать прямо по системеWindows (x86)илиWindows (x86_64), вы можете выбрать подходящий вам образ при загрузке, и двойным щелчком установить его.

4 инструмента MAT для использования

MATПозиционирование — это инструмент анализа памяти. Его основная функция — анализ снимков памяти, чтобы помочь нам найти возможные переполнения памяти или утечки памяти. Поэтому его основная цель — найти объекты, занимающие большой объем памяти, и найти объекты, которые невозможно восстановить. .Официальный документ МАТ, адрес такой:https://help.eclipse.org/2019-06/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html,правильноMATИспользование описано, и заинтересованные студенты могут подойти и посмотреть. Следующие основныеMATВводятся общие понятия и часто используемые функции.

В дальнейшем сjava-monitor-example(https://github.com/mianshenglee/my-example/tree/master/java-monitor-example)Например, этот пример является простымspring bootработает, тот что внутриcontrollerсерединаuser/oomинтерфейс называетсяserviceобъект черезListУчастники продолжают добавлятьUserобъекта, что в конечном итоге приводит кOOMпроисходит, параметры запуска приложения-Xms64m -Xmx64m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${APP_HOME}/logs/heapdump.hprof.

4.1 Описание концепции, связанной с MAT

4.1.1 Утечки памяти и переполнение памяти

  • Утечка памяти: Объект бесполезен (не требуется никакой программной логикой), и на него по-прежнему ссылается корневой элемент. Он не может быть автоматически переработан сборщиком мусора. Необходимо выяснить место и причину утечки кода. чтобы быть уверенным раствор;
  • Переполнение памяти: Объекты в памяти все еще живы, и места для выделения кучи JVM недостаточно.Необходимо проверить размер настройки кучи (-Xmx и -Xms), а также имеет ли код длительный жизненный цикл объекта и долгое время пребывания в состоянии.

4.1.2 Ссылки (сильная ссылка, мягкая ссылка, слабая ссылка, виртуальная ссылка)

  • Strong Ref(Сильная ссылка): ссылка со строгой достижимостью. Объект хранится в памяти. Только после удаления сильной достижимости объект может быть переработан. Обычно мы пишем код Strong Ref.

  • Soft Ref(Мягкая ссылка): в соответствии с мягкой доступностью, пока имеется достаточно памяти, объект будет храниться до тех пор, пока память не будет заполнена и не будет сильной ссылки. Как правило, его можно использовать для реализации кэширования, реализуемого через класс java.lang.ref.SoftReference.

  • Weak Ref(Слабая ссылка): слабее, чем Мягкая ссылка.Когда обнаруживается, что Сильная ссылка отсутствует, объект немедленно восстанавливается, не дожидаясь, пока память станет жесткой. Реализуется через классы java.lang.ref.WeakReference и java.util.WeakHashMap.

  • Phantom Ref(Виртуальная ссылка): в памяти вообще не хранится ни один объект, вы можете использовать только сам Phantom Ref. Обычно он используется для выполнения специального процесса очистки после входа в метод finalize(), который реализуется java.lang.ref.PhantomReference.

4.1.3 shallow heapиretained heap

  • shallow heap: Размер памяти, занимаемой самим объектом, то есть сумма заголовка объекта и переменных-членов (не значения переменных-членов), например, ссылка занимает 32 или 64 бита, целое число занимает 4 байта, Long занимает 8 байт и т.д. Например, простой класс имеет только одну переменную-член.int i, то этот классshallo sizeсоставляет 12 байт, поскольку заголовок объекта имеет размер 8 байт, переменные-членыintсоставляет 4 байта. Неглубокий размер обычного объекта (не массива) определяется количеством и типом его переменных-членов, а неглубокий размер массива определяется типом элементов массива (тип объекта, базовый тип) и длиной массив.
  • retained heap: Если объект освобождается, размер кучи, занимаемый всеми объектами (в том числе рекурсивно выпущенными), на которые ссылаются и которые освобождаются, будет уменьшен за счет освобождения объекта, то есть объект X может быть GC после того, как он будет утилизирован мусором. коллектор Сумма всех объектов, удаленных из памяти. По сравнению с мелкой кучей сохраненная куча может более точно отражать фактический размер объекта (если объект освобожден, сохраненная куча может быть освобождена).

4.1.4 outgoing referencesиincoming references

  • outgoing references: представляет выходной узел объекта (объект, на который ссылается объект).
  • incoming references: Указывает входной узел объекта (объект, который ссылается на объект).

4.1.5 Dominator Tree

Преобразование дерева объектов вDominator TreeЭто может помочь нам быстро найти блок, который занимает больше всего памяти, а также может помочь нам проанализировать зависимости между объектами.Dominator TreeСуществует несколько определений:

  • Объект ХDominator(доминирует) над объектом Y тогда и только тогда, когда все пути к Y в дереве объектов должны проходить через X
  • Прямой объект YDominator, относится к ближайшему Y в дереве объектовDominator
  • Dominator treeОн строится с использованием дерева объектов. существуетDominator treeКаждый объект в его непосредственномDominatorдочерний узел .

дерево объектов иDominator treeСоответствующее соотношение выглядит следующим образом:

Как показано на рисунке выше, поскольку и A, и B относятся к C, при освобождении A память C не освобождается. Таким образом, эта память не будет рассчитываться в Retained Heap A или B, поэтому дерево объектов преобразуется вDominator tree, A, B и C равны.

4.1.6 Корни сборки мусора (корень GC)

При выполнении GC судят по достижимости объекта, следует ли истребовать объект.Достижим ли объект, то есть связана ли ссылка на объект сGC Rootсвязанный. ОдинGC rootОтносится к объектам, к которым можно получить доступ из-за пределов кучи, объект может бытьGC rootобъект.

  • System Class: классы, загруженные загрузчиком классов bootstrap/system, например java.util.* в rt.jar.
  • JNI Local: параметр переменной или метода в методе JNI.
  • JNI Global: глобальные переменные в методах JNI
  • Thread Block: Переменные в потоках, объекты в живом потоке не должны быть переработаны.
  • Thread: активный поток
  • Busy Monitor: вызовите метод wait(), notify() или синхронизируйте объект, например, вызов synchronized(Object) или текущий объект после входа в синхронизированный метод.
  • Java Local: локальные переменные, такие как входные параметры метода или объекты, созданные внутри метода, которые все еще находятся в стеке потоков.
  • Native Stack: переменная или параметр метода в методе Java.
  • Finalizable: объект ожидает запуска финализатора
  • Unfinalized: объект, который имеет метод finalize, но не финализирован и не находится в очереди финализатора.
  • Unreachable: Через другие объекты, недоступные для root, MAT пометит их как root для анализа и восстановления.
  • Java Stack Frame: кадр стека Java
  • Unknown

4.2 Leak Suspects автоматически анализирует утечки

когда это произойдетOOMполучитьheapdump.hprofфайл или после ручного сброса файла используйтеMATоткрыть файл. После открытия подскажет, выполнять ли отчет об обнаружении утечек памяти по умолчанию (если вы пропустите его при открытии Дампа, вы также можете войти в панель инструментов из других входов.Run Expect System Test -> Leak Suspects),Как показано ниже:

После выбора «Да» введите содержимое отчета. Это содержимое отчета поможет нам проанализировать места, которые могут быть заподозрены в утечках памяти. Он будет отображать больший совокупный объем использования памяти в виде круговой диаграммы. Как показано ниже:

Как показано выше, в отчете указываетсяUserServiceЗанимает 76,73% памяти, и эти воспоминания находятся в массиве Object[]. Поэтому весьма вероятно, что количество массивов в этом объекте слишком велико. нажмитеDetailsВы можете просмотреть более подробную информацию:

Здесь подробно,Shortest Paths To the Accumulation Pointможет отображаться наGC rootsкратчайший путь, из которого можно проанализировать, какойGC rootподключенные провода к токуRetained HeapОбъекты, занимающие значительный размер, не могут быть переработаны.В этом примереGC rootявляется локальной переменной потока (java local).Accumulated Objects in Dominator TreeотDominator TreeДля представления удобно видеть, какой из объектов, «доминирующих» над текущим объектом, занимает наибольшую Retained Heap. На рисунке видно, что объектыArrayListв, покаArrayListподObjectмассив, под массивом находитсяUserобъект. Это может сказать, где проблема. Вам нужно посмотреть код для этого местоположения, чтобы узнать, что вызвало сохранение этого массива.Userпричина передозировки.

Примечание. В каталоге исходного файла дампа кучиMATСодержимое отчета было сжато и упаковано в ZIP-файл с именем "xxx_Leak_Suspects.zip". Весь отчет представляет собой файл в формате HTML, который можно открыть и просмотреть непосредственно в браузере, что может облегчить распространение отчета и обмен им.

4.3 Представление гистограммы для просмотра количества и размера объектов

нажмитеOverviewстраницаActions«Просмотр гистограммы» в области или нажмите кнопку «гистограмма» на панели инструментов, чтобы отобразить список гистограмм, в котором отображается количество экземпляров каждого класса класса, количество занятыхShallow heapиRetained内存Размер можно сортировать и отображать отдельно. Как показано ниже:

Shallow HeapиRetained HeapКонцепция уже обсуждалась. Для объектов Java его члены в основном являются ссылками. Настоящая память находится в куче, которая выглядит как куча нативных byte[], char[], int[], так что если смотреть только на память самого объекта, то количество очень мало, и в большинстве случаев , в представлении гистограммы классы с большим количеством объектов-экземпляров представляют собой некоторые базовые типы (обычно ранжируются первыми), такие как char[], String, byte[], поэтому невозможно определить конкретный класс или метод, вызывающий утечку памяти только из этих. На приведенном выше рисунке это видно непосредственноUserОбъектов очень много, иногда их не так просто увидеть, можно воспользоватьсяgroup result byвозможноsuper class,class loaderОжидание сортировки, особое внимание следует уделить таможеннымclassLoader,Как показано ниже:

В общем, если в представлении «Гистограмма» отображается большое количество объектов-экземпляров, которые не являются базовыми типами, а являются классами, определяемыми пользователем, или подозрительными классами, необходимо сосредоточиться на просмотре. Для дальнейшего анализа вы можете щелкнуть правой кнопкой мыши и выбрать «Использовать».List objectsилиMerge Shortest Paths to GC rootsи другие функции продолжают бурение данных. вlist objectsСоответственноoutgoing referencesиincoming references, можно узнать ссылки с этого объекта и через какие ссылки на этот объект.Merge Shortest Paths to GC rootsВы можете исключить все те, которые не являются сильными ссылками, и найти объект дляGC rootссылочный путь. Конечная цель — найти объект, занимающий наибольшую память, и объект, который нельзя переработать, вычислить путь от корня сборщика мусора до связанного объекта и проверить код по пути объекта, чтобы выяснить проблему.

4.4 Dominator TreeПосмотреть

нажмитеOverviewстраницаActionsВы можете войти в «Дерево Dominator» в области или нажать кнопку «Открыть дерево Dominator» на панели инструментов.Dominator TreeПосмотреть. В этом представлении отображается текущая память кучи в измерении экземпляра объекта.Retained HeapНаиболее занятые объекты и древовидная структура объектов, выживание которых зависит от них. Как показано ниже:

Представление показывает имя объекта экземпляра,Shallow Heapразмер,Retained Heapразмер и текущий объектRetained Heapпроцент от всей кучи. Граф имеет древовидную структуру, когда объект на предыдущем уровне перерабатывается, подобъекты, на которые он ссылается, будут перерабатываться.DominatorЭто означает, что когда родительский узел перерабатывается, дочерний узел также будет переработан. С помощью этого представления вы можете легко узнать заполняемостьRetained HeapНесколько объектов с наибольшим объемом памяти и укажите, какие объекты активны из-за каких объектов. В этом примере видно, чтоUserServiceсерединаArrayListСсылочный массив хранит слишком многоUserобъект.

4.5 Представление потоков для просмотра текущего состояния стека потоков

Нажмите кнопку «шестеренка» на панели инструментов, чтобы открытьThread OverviewПросмотр, вы можете просмотреть информацию о кадре стека потока, включая информацию об объекте потока/стеке потока, имя потока,Shallow Heap,Retained Heap, загрузчик классов, является ли это потоком демона и т. д. В сочетании с анализом дампа памяти вы можете увидеть локальные переменные в кадре стека потоков, а также увидеть значения атрибутов локальных переменных в области атрибутов объекта внизу слева. Как в примере выше (shortest paths to GC root), знайте, что это связано с многопоточностьюThread-12даGC-rootОн занимает много памяти.В представлении потока вы можете сосредоточиться на его атрибутах, как показано ниже:

Как видно из рисунка выше, этот поток вызываетWithOOMметод с использованием переменныхUserService, в то время как переменная используетuserList, который содержит большое количествоUserобъект, заниматьretained heapочень большой.

5 Резюме

Для анализа памяти java-приложений необходимо сделать дамп памяти java-приложений.После создания снимков памяти используйтеMATВыполните анализ, чтобы найти большие объекты, найти утечки или переполнения памяти, проанализировать код и решить проблему. Эта статья оMATСценарии использования, основные понятия, установка и использование . С помощью этой статьи я надеюсь помочь вам анализировать память более удобно и эффективно, а также решить проблему сбоя памяти в Java-приложениях.

Информация о параметрах

  • MATОфициальный сайт:https://www.eclipse.org/mat/
  • MATскачать:http://www.eclipse.org/mat/downloads.php
  • MATруководство:https://help.eclipse.org/2019-06/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html
  • Неглубокие и сохраненные размеры:https://www.yourkit.com/docs/java/help/sizes.jsp
  • Используйте Eclipse Memory Analyzer Tool (MAT) для анализа онлайн-ошибок (1) — вид и функции:https://www.cnblogs.com/trust-freedom/p/6744948.html
  • Пример кода адреса:https://github.com/mianshenglee/my-example/tree/master/java-monitor-example

Связанное Чтение