Что-то продолжает убивать мой процесс Java в Ubuntu, кто-нибудь знает почему? - PullRequest
7 голосов
/ 16 ноября 2011

Так что каждые пару дней мой процесс Java в Ubuntu автоматически завершается, и я не могу понять, почему.

У моего устройства 35,84 ГБ ОЗУ, когда я запускаю процесс Java, я передаю ему параметр -Xmx28g, поэтому он должен использовать намного меньше, чем максимально доступный объем ОЗУ.

Я запустил jstat следующим образом:

# jstat -gccause -t `pgrep java` 60000

Последние несколько строк вывода jstat непосредственно перед остановкой процесса были:

Time     S0     S1     E      O      P       YGC   YGCT       FGC FGCT     GCT     LGCC                 GCC
14236.1  99.98   0.00  69.80  99.40  49.88   1011  232.305    11  171.041  403.347 unknown GCCause      No GC
14296.2  93.02   0.00  65.79  99.43  49.88   1015  233.000    11  171.041  404.041 unknown GCCause      No GC
14356.1  79.20   0.00  80.50  99.55  49.88   1019  233.945    11  171.041  404.986 unknown GCCause      No GC
14416.2   0.00  99.98  24.32  99.64  49.88   1024  234.945    11  171.041  405.987 unknown GCCause      No GC

Это похоже на то, что происходило в / var / log / syslog примерно в это время: https://gist.github.com/1369135

На этом сервере действительно ничего не работает, кроме моего Java-приложения. Что происходит?

edit: Я использую java версии 1.6.0_20, единственные заметные параметры, которые я передаю java при запуске, это "-server -Xmx28g". Я не использую сервер приложений, но мое приложение встраивает «Простую веб-инфраструктуру».

Ответы [ 5 ]

7 голосов
/ 16 ноября 2011

Если предположить, что проблема в убийце OOM, то он убил ваш процесс в отчаянной попытке заставить функционировать ОС в условиях серьезного кризиса нехватки памяти.

Я бы пришел к выводу, что:

  • ваша виртуальная машина Java фактически использует более 28 ГБ;т. е. у вас значительное использование памяти без кучи, и

  • ОС не настроена с достаточным количеством пространства подкачки.

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

В качестве альтернативы, уменьшите размер кучи JVM.


Обратите внимание, что "-Xmx ..." устанавливает максимальный размер кучи, а не максимальный объем памяти, который может использовать ваша JVM.JVM помещает некоторые вещи вне кучи, включая такие вещи, как память для стеков потоков и отображаемые в память файлы, используемые вашим приложением.


Системный журнал подтверждает, что это убийца OOM на работе.

Каким образом связанный системный журнал говорит об этом?

Там написано:

Nov 15 13:53:49 ip-10-71-94-36 kernel: [3707038.606133] Out of memory: kill process 6368 (run.sh) score 4747288 or a child
Nov 15 13:53:49 ip-10-71-94-36 kernel: [3707038.606146] Killed process 9359 (java)

Консоль говорит, что Java был убит, а не что он вышел.

Правильно.Он был убит убийцей OOM операционной системы.

Если бы ему не хватило памяти, он обычно выдавал исключение OutOfMemory, чего не было.

Вот что бы произошло, если бы вы заполнили кучу Java.

Это не то, что здесь происходит.Фактическая проблема заключается в том, что физической памяти недостаточно для хранения кучи Java.Убийца OOM справляется с этим ...

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

К сожалению, вы пытаетесь использовать гораздо больше оперативной памяти, чем доступно в системе.Это вызывает сбой виртуальной памяти, затрагивая всю операционную систему.

Когда система начинает сильно перебивать, убийца OOM (не JVM) определяет ваш процесс Java как причину проблемы.Затем он убивает его (SIGKILL), чтобы защитить остальную часть системы.Если этого не произойдет, есть риск, что вся система полностью заблокируется и ее потребуется перезагрузить.


Наконец, вы сказали:

Моя коробкаимеет 35,84 ГБ ОЗУ ...

Это довольно странное значение.32 ГиБ составляют 34 359 738 368 байт или 34,35 ГБ.

Но исходя из этого и наблюдаемого поведения, я подозреваю, что это доступная виртуальная память, а не физическая ОЗУ.В качестве альтернативы вашей «коробкой» может быть виртуальная машина с включенным избыточным объемом ОЗУ на уровне гипервизора.

6 голосов
/ 16 ноября 2011

Добро пожаловать в OOM-killer, функцию linux, которая является основой приложений с большой памятью повсюду.Там нет простого рецепта, чтобы разобраться, просто Google для этого и начать читать и вооружаться.

Хотя я не могу положить свои умственные пальцы в сжатое объяснение шениганов убийцы ООМ, я помню, что критическая настройкаПараметр называется «swappiness».На одном из наших больших серверов у нас есть:

/ etc / sysctl.conf: vm.swappiness = 20

Чтение http://www.gentooexperimental.org/~patrick/weblog/archives/2009-11.html.

3 голосов
/ 16 ноября 2011

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

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

1 голос
/ 18 мая 2013

В Ubuntu есть «сторожевой» процесс, который убивает другие процессы при нехватке памяти. Смотрите справочную страницу: http://manpages.ubuntu.com/manpages/natty/man8/watchdog.8.html

1 голос
/ 16 ноября 2011

вау, у тебя реально может быть 28 Гб кучи ?! Может быть, вы должны попытаться уменьшить его, оставив не более 50% ОЗУ, я думаю (так что ~ 18 ГБ или даже 15 ГБ). Плюс 171 Full GC - это много! Как долго это приложение работало? 171 за 2-3 дня звучит огромно. Кстати, сущность указывает OOM до завершения - я думаю, что уменьшение кучи исправит это (возможно, вы ограничиваете JVM от расширения собственного пространства). Попробуйте настроить различные параметры, попробуйте, например, размер стека (-Xss). Проверьте максимальный размер перми и другие разделы. Это проблема с памятью, и это не обязательно куча.

...