У меня несколько серверов под управлением 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-битной среде выполнения или вернуться к технической поддержке поставщика (может стоить $ $) и спросить, что случилось.
В конечном итоге, если вам удастся ограничить общий объем памяти, вы просто заставите приложение вылетать раньше, и у вас все еще останется проблема.