Назад | Перейти на главную страницу

Почему процесс Java VM потребляет больше оперативной памяти, чем указано в параметре -Xmx?

У меня несколько серверов под управлением CentOS 5.4 и только одно приложение на Java VM. Я настроил виртуальную машину Java со следующими аргументами:

java -Xmx4500M -server -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:NewSize=1024m  -Djava.net.preferIPv4Stack=true -Dcom.sun.management.jmxremote=true

Машины, на которых я запускаю виртуальную машину, имеют 6 ГБ ОЗУ и не работают другие приложения. Через некоторое время java-процесс начинает очень сильно загружать пространство подкачки, я получаю эту информацию из top команда:

7658 root      25   0 11.7g 3.9g 4796 S 39.4 67.3 543:54.17 java

С другой стороны, если я подключаюсь через JConsole, он сообщает, что виртуальная машина Java использует 2,6 ГБ, зафиксировано 4,6 ГБ и макс.

java -version возвращает:

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

Почему виртуальная машина Java так сильно расширяется по сравнению с размером выделенной кучи? И куда девается эта память, если она не отображается в JConsole?

-Xmx - это максимальный объем кучи, используемый vm. Он не включает память для загруженных классов, саму виртуальную машину, стеки потоков или память, используемую, например, для JIT. Строка сверху также вводит в заблуждение, поскольку первое число включает общую память, которая также используется другими программами. Второе число 3,9 г - размер резидента и ближе к реальности.

Моя рекомендация: проверьте, действительно ли вам нужно столько кучи (количество и размер объектов), и уменьшите число -Xmx, если можете.

Я заметил ошибку в некоторых коммерческих приложениях на основе Java, где приложение хорошо работает на 32-битной Java, но требует дополнительных (и в основном ненужных) 1,25 ГБ, чтобы начать работу с 64-битной Java. Итак, то, что занимает 256 МБ в 32-битной Java, занимает 1,5 ГБ в 64-битной среде выполнения.

Я подозреваю, что Java сообщает, что, по ее мнению, использует приложение, но не сообщает о собственных накладных расходах времени выполнения, особенно в случае, когда эта ошибка вызывается.

Вы можете попробовать запустить приложение в 32-битной среде выполнения или вернуться к технической поддержке поставщика (может стоить $ $) и спросить, что случилось.

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