Дамп кучи!= Виртуальная память?

Не очень хорошо разбираясь в Java и особенно в том, что касается отладки в Java, но взяв дамп кучи в Jenkins с помощью Monitoring, а затем расшифровав его в Eclipse с помощью MAT, показывает, что общая память использовала 169,4 МБ, в то время как в мониторинге Jenkins память, кажется, постоянно используется много и GC часто работают. -XmX это 4G.

Почему у меня только 169,4 МБ с MAT? Может быть потому, что перед созданием дампа Дженкинс выполняет GC? Если так, могу ли я избежать этого, чтобы увидеть полный дамп памяти?

3 ответа

Решение

Понимание памяти

Да, дамп кучи Java и дамп виртуальной памяти (называемый "дамп памяти" или "дамп памяти" в Windows) - это разные вещи.

Дамп кучи Java содержит только память, относящуюся к Java, то есть место, где находятся объекты Java. Дамп кучи Java анализируется с помощью таких инструментов, как MAT (как вы уже упоминали) или инструмент анализа кучи Java.

Дамп сбоя Windows процесса (пользовательского режима) содержит всю виртуальную память, где виртуальная память - это термин операционной системы, предоставляющей память. В Windows это вся память, выделенная через VirtualAlloc.

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

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

В вашем случае Мониторинг очень похож на универсальный инструмент, так как он имеет дело со списком процессов и временем ЦП, но это не похоже на Java. С другой стороны, MAT явно является Java-инструментом из его описания.

Различия в памяти

Итак, насколько размер кучи Java может отличаться от размера виртуальной памяти?

Многое:

  1. Загруженные учетные записи EXE /DLL в виртуальную память, но не в кучу Java
  2. Память, используемая собственным кодом (например, через JNI), относится к виртуальной памяти, но не к куче Java
  3. Память, запрашиваемая Java у ОС, но еще не используемая Java, определенно считается виртуальной памятью, но с точки зрения Java она может считаться "свободной".

Очевидно, что инструменты, которые собирают дамп кучи, выполняют GC, чтобы уменьшить размер дампа. Так как вещи, которые могут быть GCed, не должны генерировать OOM, это скорее предназначено для обнаружения утечек памяти, чем для устранения проблем использования памяти.

ВМ запрашивает виртуальную память для хранения различных данных. Затем VM выделяет некоторую память для хранения переменных (то есть кучи), нативный код (не кучи), резервирует некоторую память, которая еще не используется. В результате виртуальная память строго больше, чем куча. Не существует какой-либо четкой корреляции между кучей и виртуальной памятью, учитывая, что вы можете написать простую бесконечную рекурсию (куча будет почти такой же большой, как виртуальная память) или загрузить большую dll в программу hello world (куча намного меньше, чем виртуальная память).

Другие вопросы по тегам