2014-02-08 5 views
3

Насколько хороша попытка улова при перехвате исключений из памяти? У меня нет опыта написания программного обеспечения, которое на низком уровне управляет собственной памятью, но я мог представить себе подход к этому.Java try catch-out of memory

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

Спасибо!

+0

http://stackoverflow.com/questions/1692230/is-it-possible-to-catch-out-of-memory-exception-in-java?rq=1 – NeilA

+0

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

ответ

1

Насколько хороша попытка улова при перехвате исключений из памяти?

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

Возможно ли, что у программы, управляющей памятью, заканчивается память?

«Программа» управляющая память - сборщик мусора. AFAIK, он всегда имеет достаточно памяти для своих целей. Хотя, если бы это было не так, у него не было бы никакой альтернативы, кроме как для жесткой аварии JVM.

Когда я могу попытаться поймать исключение из памяти, и это не уловит исключения?

Только в случае сбоя JVM. Или, если OOME загружается в другой поток стека в тот, где вы пытаетесь его поймать.

ОК, так почему ловите ОКОРОГО рискованного и/или бесполезного.

Первая причина заключается в том, что OOME может быть выброшен в любой стек потока без предупреждения. Когда вы поймаете исключение, обработчик (как правило) не имеет возможности узнать, что происходит с «up stack», и точно, как это произошло. Следовательно, он не знает, было ли повреждено или скомпрометировано состояние выполнения приложения. (Был ли поток посередине обновления чего-то важного? Был ли он уведомлять какой-то другой поток ... и поток теперь не получит уведомление?)

Вторая причина в том, что OOME's часто являются результатом Явная утечка Java ... вызванная чем-то «зависанием» на объектах, когда это не должно делать. Если вы поймаете OOME и попытаетесь возобновить ... когда проблема была вызвана утечкой ... возможно, что оскорбительные объекты по-прежнему будут доступны, а еще один OOME будет следовать довольно скоро. Другими словами, ваше приложение может застрять в состоянии, в котором оно постоянно бросается и восстанавливается от OOME. В лучшем случае это будет убивать производительность ... потому что последнее, что JVM обычно делает до того, как OOME выполняет полную сборку мусора (остановить мир). И это занимает значительное время.

Обратите внимание, что это не означает, что вы никогда не должны ловить OOME. Действительно, ловить OOME, сообщать об этом, а затем закрывать, часто является хорошей стратегией.

Нет, вещь, которая является рискованной/тщетной, заключается в том, чтобы поймать OOME, а затем попытаться восстановить и продолжить работу.

0

В java Out Of Memory не исключение, это ошибка. Вы можете делать что-либо на уровне программы, но это системное ограничение. Вы можете избежать этого, увеличив размер памяти кучи по умолчанию.

export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m" 
2

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

Однако вполне может быть вторичные проблемы:

  • Любого распределение может быть пресловутой соломинкой, которая ломает спину верблюда, так что вы, вероятно, не будете знать, где ваш код будет выдавать ошибку ООМ , Это может произойти даже в совершенно другом потоке от того, на котором вы работаете в своей памяти, и, таким образом, разбивая совершенно разные части JVM.
  • В зависимости от того, что вы собираетесь делать, когда вы его поймаете, вы можете выделять больше памяти (например, LogRecord или StringBuilder, последняя из которых может даже произойти неявно как часть синтаксического конкатенации строк), что могло бы снова закончилась память.

Эти проблемы применимы только в том случае, если у вас заканчивается память «обычный путь»; то есть путем выделения множества «нормальных» объектов. В отличие от этого, если работа, заканчивающаяся памятью, представляет собой, например, одиночное распределение, скажем, массива 10 ГБ, то они не создают проблемы.

-4


Прежде всего, из памяти ошибка в java не исключение. Мы можем обрабатывать только исключения из java, используя предложение try-catch или предложение throws.

Оба класса ошибок и исключений расширяют класс Throwable. Но ошибка является безвозвратным условием, а исключение - способным.

Для вашей ситуации перейдите в сборку мусора в java.

+2

Это неправда. Все «Throwable's» являются увлекательными, и ошибки такие. – Dolda2000

+0

Только по соглашению обрабатывается исключение, и только по соглашению следует оставлять ошибки в одиночку. Вы можете «поймать (Throwable t)» и просто «не заботьтесь», что было бы ужасно. – Makoto

+0

@ Dolda2000, пожалуйста, дайте пример, иначе я не согласен с вами. – iCodeCademy

0

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

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