Подтвердить что ты не робот

JVM превышает максимальную память, определенную с помощью -Xmx

У нас есть Java webapp, который мы обновили с Java 1.5.0.19 до Java 1.6.0.21

/usr/java/jdk1.6.0_21/bin/java -server -Xms2000m -Xmx3000m -XX:MaxPermSize=256m -Djava.awt.headless=true -Dwg.environment=production -Djava.io.tmpdir=/var/cache/jetty -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=31377 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/webapp -Dprogram.name=run.sh -Djava.endorsed.dirs=/opt/3p/jboss/lib/endorsed -classpath /opt/3p/jboss/bin/run.jar:/usr/java/jdk1.6.0_21/lib/tools.jar org.jboss.Main -c default

Как вы можете видеть, он должен предварительно распределить 2 ГБ кучи и максимум на 3 ГБ (почему мы превалируем так много, потому что это приложение является древним и плохо спроектированным, поэтому есть масса вещей для загрузки). Проблема, которую мы видели недавно после перехода на 1.6, заключается в том, что иногда память проходит через крышу. В то время как использование памяти, скорее всего, связано с приложением, JVM превышает настройку max 3GB для кучи. Используя верхнюю часть, я вижу:

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND    
8449 apache    18   0 19.6g 6.9g 5648 S  4.0 84.8  80:42.27 java             

Итак, как может быть JVM с кучей 3 ГБ, 650 Мбайт и даже некоторые накладные расходы потребляют 6,9 ГБ? Ошибка в JVM, которая будет исправлена ​​путем обновления до сборки № 35? Что-то не хватает на то, что в java может использовать дополнительную память? Просто пытаюсь увидеть, видел ли кто-нибудь это раньше.

4b9b3361

Ответ 1

Итак, как может JVM с кучей 3 ГБ, 650 Мбайт и даже некоторые издержки потребляют 6,9 ГБ?

Возможные пояснения:

  • много и много стеков потоков,
  • файлы с отображением памяти, которые не закрываются, когда они должны быть,
  • некоторая собственная библиотека кода, использующая (возможно, утечку) память из кучи.

Я был бы склонен обвинять приложение, прежде чем обвинять JVM.

Ответ 2

Короче говоря, моя первоначальная реакция была правильной, это была ошибка в JVM. Мы использовали 1.6.0_21, и оказалось, что мы испытывали ту же ошибку, что и в https://confluence.atlassian.com/pages/viewpage.action?pageId=219023686. Обновление до 1.6.0_37 устранило проблему, и мы перешли от ежедневных сбоев до 2 недель без сбоев.

Таким образом, хотя настроение не просто обвинять JVM - хорошая политика, кажется, что также следует посоветовать не всегда предполагать, что JVM является ошибкой, так как все программное обеспечение имеет случайную ошибку. Плюс, кажется хорошей политикой, чтобы поддерживать актуальность.

Спасибо за помощь в этом!

Ответ 3

http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html

Обратите внимание, что JVM использует больше памяти, чем просто кучу. Например В памяти выделяются методы Java, стеки потоков и собственные дескрипторы отдельно от кучи, а также внутренние структуры данных JVM.

Итак, если у вас много потоков и много встроенных ручек, память может превышать ограничение кучи. Вы уверены, что этого не произошло раньше?

Также проверьте следующее: Java использует больше памяти, чем выделенная память