Sun JVM использует виртуальную память с высоким потреблением - PullRequest
2 голосов
/ 06 августа 2010

У нас есть рабочий сервер Tomcat (6.0.18), который работает со следующими настройками:

-server -Xms7000M -Xmx7000M -Xss128k -XX:+UseFastAccessorMethods 
-XX:+HeapDumpOnOutOfMemoryError -Dcom.sun.management.jmxremote.port=7009 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false -verbose:gc -XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=/opt/apache-tomcat-6.0.18/conf/logging.properties 
-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n 
-Djava.endorsed.dirs=/opt/apache-tomcat-6.0.18/endorsed 
-classpath :/opt/apache-tomcat-6.0.18/bin/bootstrap.jar

java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) 64-Bit Server VM (build 11.2-b01, mixed mode)

Через некоторое время работы (через JConsole) мы получаем следующее потребление памяти:

Current heap size: 3 034 233 kbytes
Maximum heap size: 6 504 832 kbytes
Committed memory:  6 504 832 kbytes
Pending finalization: 0 objects
Garbage collector: Name = 'PS MarkSweep', Collections = 128, Total time spent = 16 minutes
Garbage collector: Name = 'PS Scavenge', Collections = 1 791, Total time spent = 17 minutes

Operating System: Linux 2.6.26-2-amd64
Architecture: amd64
Number of processors: 2

Committed virtual memory: 9 148 856 kbytes
Total physical memory:  8 199 684 kbytes
Free physical memory:     48 060 kbytes
Total swap space: 19 800 072 kbytes
Free swap space: 15 910 212 kbytes

Вопрос в том, почему у нас много выделенной виртуальной памяти?Обратите внимание, что максимальный размер кучи составляет ~ 7 ГБ (как и ожидалось, поскольку Xmx = 7 ГБ).

top показывает следующее:

31413 root  18  -2 8970m 7.1g  39m S   90 90.3 351:17.87 java

Зачем JVM нужны дополнительные 2 ГБ!виртуальной памяти?Могу ли я получить распределение памяти без кучи, как в JRockit http://blogs.oracle.com/jrockit/2009/02/why_is_my_jvm_process_larger_t.html?

Редактировать 1: Пермь 36M.

Ответы [ 4 ]

2 голосов
/ 10 января 2012

-Xms7000M -Xmx7000M

Что для меня говорит JVM: «выделите 7 ГБ в качестве начального размера кучи с максимумом 7 ГБ».

Так чтоПроцесс всегда будет 7 ГБ для ОС, поскольку это то, что JVM запрашивает через флаг Xms.То, что он на самом деле использует для JVM - это размер кучи в несколько сотен мегабайт.Обычно вы устанавливаете высокий Xms, когда предотвращаете замедления из-за чрезмерного сбора мусора.Когда JVM достигает (определенного JVM) процента используемой памяти, он выполняет быструю сборку мусора.если это не освобождает память, тогда он попытается создать отдельную коллекцию.Наконец, если это не удастся и максимальный объем памяти, определенный Xmx, не будет достигнут, он запросит у ОС больше памяти.Все это требует времени и может реально заметить на рабочем сервере - это заранее предотвращает это.

1 голос
/ 26 апреля 2013

Я не знаком с jconsole, но вы уверены, что JVM использует дополнительные 2 Гб?Мне кажется, что это ОС или другие процессы, которые приносят общий объем до 9 ГБ.

Кроме того, общее объяснение того, что JVM использует значительно больше виртуальной памяти, чем позволяет параметр -Xmx, состоит в том, что у васmapped-файлы (MappedByteBuffer) или используйте библиотеку, которая использует MappedByteBuffer.

1 голос
/ 07 марта 2011

Похоже, что эта проблема была вызвана очень большим количеством ошибок страниц, которые были у JVM. Скорее всего, когда JVM Sun испытывает много сбоев страниц, она начинает выделять дополнительную виртуальную память (все еще не знаю почему), что, в свою очередь, может еще больше увеличить нагрузку ввода-вывода и так далее. В результате мы получили очень высокое потребление виртуальной памяти и периодические зависания (до 30 минут) на полном GC.

Три вещи помогли нам получить стабильную работу на производстве:

  1. Снижение склонности ядра Linux к обмену (описание см. Здесь Что такое параметр ядра Linux vm.swappiness? ) очень помогло. У нас есть vm.swappiness=20 на всех серверах Linux, которые выполняют сложные фоновые задачи JVM.

  2. Уменьшите значение максимального размера кучи (-Xmx), чтобы предотвратить чрезмерное давление на саму ОС. Теперь у нас есть 9 ГБ на машинах 12 ГБ.

  3. И последнее, но очень важное - профилирование кода и оптимизация узких мест выделения памяти для максимально возможного устранения пакетов выделения.

Вот и все. Теперь серверы работают очень хорошо.

1 голос
/ 06 августа 2010

Возможно, вы захотите попытаться подключить JConsole к вашей JVM и посмотреть на выделение памяти ... Может быть, ваше пермское пространство занимает дополнительные 2 ГБ ... Куча - это только часть того, что нужно вашей виртуальной машине для работы ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...