Java отказывается запускаться - не удалось зарезервировать достаточно места для кучи объектов - PullRequest
48 голосов
/ 29 июня 2009

Фон

У нас есть пул приблизительно из 20 Linux-блейдов. Некоторые используют Suse, некоторые используют Redhat. ВСЕ разделяют пространство NAS, которое содержит следующие 3 папки:

  • / NAS / app / java - символическая ссылка, указывающая на установку Java JDK. В настоящее время версия 1.5.0_10
  • / NAS / app / lib - символическая ссылка, указывающая на версию нашего приложения.
  • / NAS / data - каталог, в который записывается наш вывод

Все наши машины имеют 2 процессора (гиперпоточные) с 4 ГБ физической памяти и 4 ГБ пространства подкачки. Мы ограничиваем количество «заданий», которые каждая машина может обрабатывать в данный момент времени, до 6 (это число, вероятно, должно измениться, но это не влияет на текущую проблему, поэтому, пожалуйста, пока игнорируйте его).

Некоторые из наших заданий устанавливают максимальный размер кучи 512 МБ, некоторые другие резервируют максимальный размер кучи 2048 МБ. Опять же, мы понимаем, что можем перебрать имеющуюся память, если на одном компьютере запущено 6 заданий с размером кучи 2048, но, насколько нам известно, этого еще не произошло.

Проблема

Время от времени задание немедленно завершается неудачей со следующим сообщением:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Мы записывали это на слишком много заданий, выполняемых одновременно на одной машине. Проблема возникала достаточно редко ( МОЖЕТ раз в месяц), что мы просто перезапускаем ее, и все будет хорошо.

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

Мы вышли на отдельные машины и попытались выполнить их вручную с тем же результатом.

Debugging

Оказывается, проблема существует только для наших коробок SuSE. Причина, по которой это происходит чаще, заключается в том, что мы добавили больше машин, а новые - SuSE.

'cat / proc / version' на полях SuSE дает нам:

Linux version 2.6.5-7.244-bigsmp (geeko@buildhost) (gcc version 3.3.3 (SuSE Linux)) #1 SMP Mon Dec 12 18:32:25 UTC 2005

'cat / proc / version' на полях RedHat дает нам:

Linux version 2.4.21-32.0.1.ELsmp (bhcompile@bugs.build.redhat.com) (gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-52)) #1 SMP Tue May 17 17:52:23 EDT 2005

'uname -a' дает нам следующее для ОБА типов машин:

UTC 2005 i686 i686 i386 GNU/Linux

На компьютере не выполняется никаких заданий, и никакие другие процессы не используют много памяти. Все процессы, в настоящее время работающие , могут использовать 100 МБ.

«top» в настоящее время показывает следующее:

Mem:   4146528k total,  3536360k used,   610168k free,   132136k buffers
Swap:  4194288k total,        0k used,  4194288k free,  3283908k cached

'vmstat' в настоящее время показывает следующее:

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy id wa
0  0      0 610292 132136 3283908    0    0     0     2   26    15  0  0 100  0

Если мы запускаем задание со следующей командной строкой (Max Heap из 1850mb), то все начинается нормально:

java/bin/java -Xmx1850M -cp helloworld.jar HelloWorld
Hello World

Если увеличить максимальный размер кучи до 1875 МБ, произойдет сбой:

java/bin/java -Xmx1875M -cp helloworld.jar HelloWorld
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Совершенно очевидно, что используемая в данный момент память предназначена для буферизации / кеширования, и поэтому так мало отображается как «свободная». Неясно, почему существует волшебная строка в 1850 Мб, где что-то выше означает, что Java не может запуститься.

Любые объяснения будут с благодарностью.

Ответы [ 15 ]

2 голосов
/ 29 июня 2009

Это может быть далеко от следа, но есть две вещи, которые приходят на ум. Оба следующих предположения предполагают, что вы используете 32-битную версию Linux.

В linux существует ограничение на размер процесса, кажется, помните, что в CentOS было около 2,5 ГБ, и оно настроено в ядре (то есть, для изменения). Ваш процесс может столкнуться с тем, что после добавления всего кода JVM + пространства Permgen и всех остальных библиотек JVM.

Во-вторых, я столкнулся с тем, что вам может не хватать адресного пространства, звучит странно, я знаю. У меня была проблема с запуском Glassfish с кучей 1,5 Гб, когда он пытался завершить JSP, мой разветвленный javac потерпел неудачу, потому что ОС не могла выделить достаточно адресного пространства для вновь созданного процесса, даже если в коробке было 12 Гб памяти. Здесь может происходить нечто подобное.

Боюсь, что единственные решения для двух вышеперечисленных - обновить 64-битное ядро.

Надеюсь, это пригодится.

1 голос
/ 27 марта 2012

Я использую SOA env. Уменьшенный Xmx с 1024 до 768 в setSOADomainENV.cmd решил проблему.

REM set DEFAULT_MEM_ARGS=-Xms512m -Xmx1024m
set DEFAULT_MEM_ARGS=-Xms512m -Xmx768m
1 голос
/ 29 июня 2009

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

sysctl -a

На машинах SuSE и RedHat, чтобы увидеть, есть ли различия? Я предполагаю, что конфигурации по умолчанию отличаются между этими двумя дистрибутивами, которые вызывают это.

1 голос
/ 29 июня 2009

Какая JVM используется? Я знаю, что BEA JRockit не превышает 1850 МБ для максимального размера кучи. Он не дает сбоя, но предупреждает пользователя о том, что он не будет использовать более 1850 МБ.

Я не знаю, почему существует такой предел, но я знаю, что он существует для BEA JRockit.

С уважением.

0 голосов
/ 11 сентября 2011

В Windows я решил эту проблему, отредактировав файл /bin/cassandra.bat напрямую, изменив значение параметров «Xms» и «Xmx» JVM_OPTS. Вы можете попробовать отредактировать файл / bin / cassandra. В этом файле я вижу закомментированную переменную JVM_OPTS, попробуйте раскомментировать и отредактировать ее.

...