Разница между объемом памяти приложения JVM и памятью ОС

Я знаю, что этот вопрос уже обсуждался, но я не мог найти способ обрести душевное равновесие.

В основном у нас есть Java-приложение, которое работает на сервере приложений Tomcat, а именно:

  • Java HotSpot (TM) 64-битная серверная виртуальная машина; 1.8.0_112; 25,112-B15; смешанный режим
  • Tomcat 7.0_Tomcat7.0.73
  • Windows Server 2012 R2 (6.3.9600)

В нашем приложении слишком много памяти, поэтому мы начинаем его профилировать; но я не могу понять простую разницу, которую я вижу между потреблением памяти приложения (куча / не куча) и памяти в ОС:

Yourkit Profiler:

Здесь объем памяти составляет 4,1 ГБ (выделенная куча) плюс 660 МБ (не куча, поэтому Metaspace, кэш кода, сжатое пространство классов), таким образом, всего 4,7 ГБ

Память Windows:

Здесь я вижу 6,266 ГБ памяти, активно используемой процессом Tomcat

Как измерить разницу в 1,5 Гб?

Это только для самого приложения Tomcat? Время выполнения JVM? Если да, то как я могу это измерить?

Изменить: эта разница, кажется, со временем увеличивается после запуска сервера приложений (Tomcat); Первоначально сумма Heap/Non Heap довольно близка к памяти, используемой процессом Tomcat, как записано в ОС, затем после нескольких часов / дней она имеет тенденцию к росту.

Изменить 2: наши параметры JAVA на сервере Tomcat

-Xms512m
-Xmx6144m
-Dlog=production
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-Djava.util.Arrays.useLegacyMergeSort=true
-Duser.country=IT
-Duser.language=it
-XX:+UseG1GC
-XX:+UseStringDeduplication

Спасибо

1 ответ

Java Allocated Heap и Windows Working Set - это не одно и то же.

Разница в 1,5 ГБ из-за того, что память обращается к Windows. Чтобы объяснить это, вот факты, которые я считаю наиболее актуальными:

  • "xmx" - 6 ГБ
  • Вы находитесь на Windows
  • "Лимит" на вашем графике составляет 5,3 ГБ.
  • Вы видите это только после того, как сервер работал в течение нескольких дней

В Windows JVM необходим непрерывный блок виртуальной памяти для кучи. Когда приложение запустится, оно будет адресовано 6 ГБ, но физически выделит только то значение, которое вы изначально установили для "xms". По мере выполнения приложения оно в конечном итоге будет выделять больше памяти для кучи до 6 ГБ минус все, что вам нужно для памяти без кучи (например, Metaspace для Java 8+). Объем памяти без кучи должен оставаться почти постоянным на уровне 660 МБ, и, кроме того, может быть дополнительная память для самой JVM (я думаю, 128 МБ).

Ваша диаграмма из профиля показывает, что в настоящее время выделено 4,1 ГБ, но существует ограничение в 5,3 ГБ. Я полагаю, что "предел" - это максимальный объем пространства, доступного для кучи, и предполагается, что он эквивалентен значению "xmx" минус метапространство. Вполне возможно, что 100% этого предельного значения будет сообщено как зафиксированное в операционной системе из-за необходимости иметь непрерывный блок памяти для кучи Java.

5,3 ГБ + 660 МБ = 5960+ МБ (возможно, больше в зависимости от того, как был ограничен лимит). Если мы предположим, что это на самом деле добавляет к вашему значению xmx 6144, тогда 128 МБ для JVM = 6272 МБ, что чуть-чуть больше, чем ваши 6266 МБ, которые, по словам Windows, являются частными.

Единственный вопрос, который остается: почему ваша виртуальная машина Java физически адресовала всю доступную кучу, если для xms установлено значение 512 МБ? Ответ заключается в том, что он подумал, что по какой-то причине потребуется физическая адресация всей кучи. Очевидно, что в то время, когда вы его профилируете, это не так, но это довольно большой провал в вашем графике, когда он выполняет сборку мусора (например, 1 ГБ, выпущенный за один раз?). Стандартные ответы на это:

  • У вас может быть утечка памяти - этот график выглядит подозрительно
  • Возможно, JVM требовалось больше оперативной памяти по какой-то совершенно веской причине, о которой вы не знаете (например, при большой нагрузке).

Но когда виртуальная машина фактически выделяет ОЗУ, она редко отдает ее обратно. Это возможно, и с G1GC он должен делать это чаще, чем с другими сборщиками мусора, но вы не должны предполагать, что рабочий набор, который видит операционная система, действительно выйдет из строя.

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