Используя jdk1.8.0_152
, я пытаюсь отследить, какая часть моей Java-программы использует больше всего памяти (в основном в куче)
Используя top
, я вижу, что весь процесс использует около 1,109 ГБ остаточной памяти.
Используя jcmd {PID} VM.native_memory
, я вижу, что общий зарезервированный объем составляет 4704896 КБ, а зафиксированный - около 1290820 КБ. Committed - это немного больше, чем остаточная память, но я читал, что не вся зафиксированная память могла быть выгружена в фактическую память, поэтому меня не очень беспокоит эта разница.
Сейчас меня больше всего беспокоит разница между использованием памяти кучи из VM.native_memory
и общим использованием кучи, когда я использую jcmd {PID} GC.class_histogram
.
Я также попытался сравнить использование кучи, используя jstat -gc {PID}
, и получил результаты, аналогичные GC.class_histogram
Согласно GC.class_histogram
и jstat -gc
, использование кучи составляет около 250 МБ, но использование VM.native_memory
кучи (зафиксировано в разделе Java Heap
) составляет около 1000000 КБ (то есть немного меньше 1 ГБ), но фактическая память RSS, похоже, ближе к общему объему, зафиксированному в VM.native_memory
Сейчас я предполагаю, что VM.native_memory
Java Heap содержит память, которая не собиралась сборщиком мусора, но даже когда я запускаю сборку мусора, я вижу, что результат jstat -gc
резко уменьшается, а VM.native_memory
вообще не затрагивается (хотя я слышал, как пользователь вручную вызов сборки мусора не всегда приводит к полной сборке мусора, но, по крайней мере, кажется, что jstat -gc
соответствует результату GC.class_histogram
.
Еще я слышал, что остаточная память из top
не всегда освобождается, когда процесс, использующий память, освобождает ее до тех пор, пока эта память не будет освобождена абсолютно.
Итак, чтобы подвести итог
- Почему
VM.native_memory
показывает другое использование памяти кучи, чемjstat
иGC.class_histogram
? - Какую метрику мне следует использовать, чтобы узнать, сколько памяти использует мой Java-процесс? (учитывая, что остаточная память в
top
может не всегда отражать фактическое использование)
top
говорит, что процесс использует, кажется, что следует использовать зафиксированные? (хотя остаточная память может относиться к общей памяти, заблокированной jvm, по сравнению с памятью, фактически заполненной объектами. Но, согласно принятой документации, похоже, относится к объектам, фактически заполняющим эту память) - person markk   schedule 30.09.2019committed
? - person markk   schedule 30.09.2019