2010-11-10 5 views
5

У меня есть критический процесс, выполняющийся в java (1.6), с зарегистрированным крючком остановки. В некоторых случаях, когда я получаю проблему с OOM (подробнее об этой проблеме ниже), процесс внезапно прекращается, я не получаю ни одного из моих журналов, мой catch (Throable x) не вылавливает исключение.jvm: можно ли узнать, что процесс завершается из-за OOM, когда он находится в режиме ожидания?

Но работает крюк отключения. Поэтому, если бы был способ узнать, что процесс будет завершен из-за какого-то неприятного OOM, я могу записать необходимую информацию перед выходом.

Есть ли способ сделать это?

О OOM: Не знаете, в чем исключение, потому что, как я уже сказал, оно не попадается. Я знаю, что это OOM, потому что я начинаю процесс с

-XX:+HeapDumpOnOutOfMemoryError 

и я получаю файл дампа кучи. В других случаях исключение поймано, и это ava.lang.OutOfMemoryError: превышение верхнего предела GC. Но не уверен, что это всегда так.

EDIT:

В случае не ясно: Я не пытаюсь, чтобы предотвратить OOM, как это может произойти по уважительным причинам в какой-то сценарий, я просто хочу, чтобы убедиться, что это ясно в файлы журналов приложений

Мой вопрос:: можно ли узнать, что процесс завершается из-за OOM во время остановки?

Мне нужно сделать это программно и из того же процесса.

На данный момент лучший подход - это увидеть, существует ли файл дампа кучи java_pid_pid process_.hprof (я знаю pid) с недавней датой и выводом было OOM. Я предполагаю, что я мог бы попробовать Runtime.getRuntime(). FreeMemory() и сообщить об ошибке, если доступная память очень низкая, но не уверен, насколько это надежно, возможно, когда процесс завершает работу, он уже выпустил много памяти, подход выше, я думаю.

+0

Итак, ваш вопрос: «Что происходит?» - правильно? – dacwe

+0

Не сердитесь на вопрос, но вы поймаете (исключение x) или поймаете (Throable x), поскольку OOM Throable, я уверен, что вы это знаете, и вряд ли это поймает, если это произойдет, но все же стоит проверить ... –

+0

как я упоминаю (может быть, не ясно, я снова отредактирую) У меня есть catch (Throable x), не имеет эффекта. спасибо – Persimmonium

ответ

3

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

Попробуйте установить default uncaught exception handler. Он поймает все неискушенные исключения.

+0

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

+0

Точно. Я не был достаточно ясен - он мог бы бросить новый OOM и не запускать код, предназначенный для этого. Я редактировал сообщение. –

2

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

Возможно, размещение вашего приложения в качестве дешифратора Unix или службы Windows будет более подходящим.

Но как насчет исследования утечки памяти с помощью инструментов для профилирования?

jvisualvm является хорошим один

0

Вы можете (технически) поймать OutOfMemoryErrors, но он не уверен, что вы сможете выполнить код в блоке catch, если памяти нет.

Возможно, стоит попробовать (1) поймать OOM, (2) сборку мусора триггера (System.gc()) и попытаться написать что-то в журнал или консоль. Нет гарантии, но ничего не сломает.

+0

Насколько я понимаю, System.gc() следует автоматически вызывать перед OOM, проблема в том, что после или во время gc OOM все еще происходит –

0

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

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

Что касается конкретной ошибки, которую вы получаете, ознакомьтесь с этим вопросом SO: Error java.lang.OutOfMemoryError: GC overhead limit exceeded - кажется, что самым простым решением будет увеличить размер вашей кучи.

+0

проблема заключается в том, что журналы не показывают ничего о проблеме OOM, поэтому я пытаюсь ее решить. OOM может случиться как некоторые допустимые варианты использования, и мне просто нужно сигнализировать об этом в файлах журналов. – Persimmonium

+0

@raticulin - Нет, OOM может * не * произойти в «действительных» случаях использования. В любом приложении. Если у вас есть варианты использования, которые могут превышать объем доступной памяти, вам необходимо признать, что до того, как на самом деле закончится нехватка памяти. Возможно, вы должны задать вопрос о том, как достичь этого ... – Anon

+0

И подсказка: «Мягкие ссылки» - один из способов написать код, который изящно обрабатывает ситуацию «нужно слишком много памяти». – Anon

0

Опять же, использование jvisualvm (JDK 6, в папке bin), как предлагается другими или другими инструментами профилирования, - лучший способ решить проблему, а не обрабатывать ее, но при условии, что вы будете самостоятельно исследовать причины OOM и попробуйте чтобы искоренить их, я бы подумал о том, чтобы сделать следующий POC (см. также ответ Алоиса)

Как насчет запуска процесса Java, который завершит вызов процесса металофикации OOM?

Вы можете поймать любой результат посылается в выходной поток вызываемого процесса, и посмотреть, если есть последовательный код выхода/трассировки стека можно использовать для идентификации OOMS

Я уверен, что есть больше подходы, но это кажется мне хорошей, программной отправной точкой

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

  • Нет связанных вопросов^_^