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

Как мой jre выходит за пределы кучи?

У меня есть jvm, фактическое использование памяти которого значительно превышает пределы, с которыми он запускается. Это виртуальная машина Sun:

root@jira:/opt/atlassian/jira/jre# ./bin/java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)

и он был настроен с максимальной кучей 768 МБ (-Xmx768m) и максимальное разрешение 256 МБ (-XX:MaxPermSize=256m), но процессы значительно превышают 1 ГБ, в настоящее время - 1,7 ГБ.

Я привык к Java-приложениям с утечками памяти, которые убивают себя с помощью OutOfMemoryErrors, когда они превышают свои пределы, а не убиваются извне, когда Linux OOMKiller запускает процессы съемки.

Из ps:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
jira     23030  2.7 70.5 2181356 1457748 ?     Sl   Nov30  34:52 /opt/atlassian/jira/jre//bin/java -Djava.util.logging.config.file=/opt/atlassian/jira/conf/logging.properties -XX:MaxPermSize=256m -Xms256m -Xmx768m

Там 1,5 ГБ, и он будет продолжать расти, пока коробка на 2 ГБ не начнет заменяться.

Что я не понимаю в отношении ограничений памяти JVM?

Предел кучи - это предел кучи JVM, представленный приложениям Java (никакая программа Java не может выделить больше, чем этот объем пространства в куче), но не ограничивает размер процесса Java (который включает кучу JVM, которую вы ' re limit, плюс любые элементы, выделенные самой JVM, плюс стек (для JVM и вашего Java-приложения), плюс другие вещи, которые я почти наверняка упускаю.

Обычно вы не увидите раздувания более чем на 10-15% сверх установленных вами пределов, но патологические случаи, вероятно, существуют, и может даже быть утечка памяти или другая ошибка в самой среде выполнения java (удачи в отладке этой свиньи).

Если вы хотите ограничить размер среды выполнения Java на уровне ОС, вам, вероятно, следует обратиться к ulimit команда. JVM может изящно обрабатывать эти ограничения.

Есть область вне кучи, которая включает память, выделенную кодом JNI и буферами Direct Byte. Вы можете контролировать последнее, используя -XX:MaxDirectMemorySize.