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 есть вся память, доступная в системе, и вся система работает медленно.
Есть ли какой-нибудь (элегантный) надежный способ обнаружить это, что мне не хватает?
Если в вашей второй попытки не происходит исключение, почему вы уверены, что 'longWork()' действительно не удалось из-за недостаточно памяти? –
Дело в том, что какое-то время обновление статуса не происходит, раб будет убит, несмотря ни на что. И тогда возникает необходимость узнать, умер ли он OutOfMemory или по какой-то другой причине. – Marco