2014-10-08 4 views
1

TL; DR: Есть ли надежный способ (!), Который я могу обнаружить из моей главной JVM, что моя подчиненная JVM, созданная с помощью 2 промежуточных скриптов, испытала ошибку OutOfMemory в Linux?Неверное обнаружение OutOfmemory в Java

Длинная версия:

Я бегу своего рода запуска приложений. В основном он получает некоторый вклад и реагирует, создавая подчиненное Java-приложение для обработки указанного ввода. Это происходит через скрипт python (чтобы правильно обрабатывать удаленные команды kill для него), который, в свою очередь, вызывает сценарий bash (генерируемый Gradle и настраивает путь к классам), чтобы фактически запустить ведомый. Ведомый содержит рабочий поток и поток монитора, чтобы сделать обратные вызовы на удаленный хост для обновлений статуса. Если обновления статуса не выполняются в течение установленного промежутка времени, раб убивается пусковой установкой. Причина, по которой он не отвечает CAN, - это OutOfMemoryError, однако это могут быть и другие причины. Мне нужно отличить OutOfMemoryError от slave от некоторой другой ошибки, из-за которой он перестает работать. Я не просто хочу отслеживать использование памяти и говорить, как только она достигает 90% «нормально, этого достаточно». Вполне возможно, что GC успешно очистится для завершения рабочей нагрузки. Я только хочу знать, не удалось ли его очистить, а JVM умер, потому что недостаточно памяти можно было освободить.

То, что я пробовал:

  • Используйте -XX: OnOutOfMemory флаг в качестве опции JVM для ведомого устройства, который вызывает скрипт, который, в свою очередь, создает файл пустой флаг. Затем я проверяю с помощью пусковой установки наличие файла флага, если раб умер. Работала как шарм в Windows, вообще не работала в Unix, потому что есть фанковая ошибка, из-за которой выполнение вызова флага требует того же количества Xmx, что и ведомое устройство. См. https://bugs.openjdk.java.net/browse/JDK-8027434 об ошибке. => Решение отбрасывается, потому что ведомому требуется полная память машины.

  • try{ longWork(); } catch (OutOfMemoryError e) { createOomFlagFile(); System.exit(100); } Это действительно работает в некоторых случаях. Однако есть также случаи, когда этого не происходит, и поток монитора просто прекращает отправку обновлений статуса. Исключение не происходит, файл флага OOM не создается. Я знаю, что SSHing на машине, хотя в Java есть вся память, доступная в системе, и вся система работает медленно.

Есть ли какой-нибудь (элегантный) надежный способ обнаружить это, что мне не хватает?

+0

Если в вашей второй попытки не происходит исключение, почему вы уверены, что 'longWork()' действительно не удалось из-за недостаточно памяти? –

+0

Дело в том, что какое-то время обновление статуса не происходит, раб будет убит, несмотря ни на что. И тогда возникает необходимость узнать, умер ли он OutOfMemory или по какой-то другой причине. – Marco

ответ

2

Вам не следует ждать OutOfMemory. Мое предложение состоит в том, что вы отслеживаете потребление памяти из главного приложения через Java Management Beans и выдаете предупреждения, когда потребление памяти становится критическим. Я никогда не делал этого сам по себе, поэтому я не могу более точно узнать, как это сделать, но, может быть, вы узнаете, или некоторые другие могут предоставить решение.

Edit: это соответствующая MXBean http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html

+1

Вот несколько примеров: http://stackoverflow.com/questions/1759831/how-do-i-access-memory-usage-programmatically-via-jmx – user3001

+0

Просто потому, что память критически низка, это не значит, что она будет) оставаться таким образом или b) что GC не сработает. Поэтому вместо этого я действительно хочу определить, не сработал ли GC, и потребление памяти убило JVM. – Marco

+0

Теперь я решил это, запустив сторожевой поток в подчиненном устройстве, который контролирует потребление памяти через 'Runtime.getTotalMemory()' и 'Runtime.getMaxMemory()'. MXBean не был полезен, потому что он возвращал значения, которые не соответствовали тому, что рассказывал мне Linux. Когда порог превышен, создается файл флага. Если раб умирает неестественной смертью, пусковая установка проверяет наличие файла флага и действует на него. – Marco

Смежные вопросы