Гарантируются ли JVM запускать GC до того, как они сгенерируют OutOfMemoryError? - PullRequest
3 голосов
/ 06 января 2012

Эта тема , а эта страница :

Это [OutOfMemoryError] никогда не будет выброшено, если JVM не попробует полную сборку мусора во-первых, включая удаление объектов со слабой / слабой ссылкой.

Что касается этого куска кода,

//.. allocate reserved memory
try {
    //.. calculation which requires alot of memory even after optimized
} catch (java.lang.OutOfMemoryError e){
    System.gc(); 
    //.. hedge recovery
}

Является ли вызов на System.gc() избыточным?

Уже гарантировано , что JVM (в соответствии с JVMS ) уже запускали GC перед броском java.lang.OutOfMemoryError?

Ответы [ 3 ]

8 голосов
/ 06 января 2012

Никогда не пытайтесь восстанавливаться из ошибки OutOfMemoryError, запуская System.gc ().Независимо от того, строго ли это гарантировано, вы можете найти его в JLS.Но это довольно плохая идея насквозь - JVM будет стараться изо всех сил, чтобы удовлетворить ваши желания выделения памяти.Когда он сдается и бросает OOM, игра заканчивается.Или уменьшите использование памяти или увеличьте размер кучи, а затем повторите попытку.

Чтобы более прямо ответить на ваш вопрос, перехват OutOfMemoryError не означает, что GC запущен.Например,

try {
    throw new OutOfMemoryError();
} catch (OutOfMemoryError e) {
    ;
}

, вероятно, не будет вызывать GC.Очевидно, это абсурдный пример.Более реалистичным, который я видел недавно, был OOME с причиной «Не удалось выделить новый собственный поток».Выполнение GC, скорее всего, не разрешит подобную ситуацию, поскольку у JVM есть свободное пространство в куче, но система не допустит больше потоков.

6 голосов
/ 06 января 2012

С здесь :

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

Итак, исключение OutOfMemoryException после GC не может освободить больше памяти.

1 голос
/ 19 марта 2015

Существует несколько различных типов OutOfMemoryError.Если мы, например, получаем OOME из-за «Невозможно создать новый собственный поток», то это не обязательно из-за вызова GC.То же самое с «Запрошенный размер массива превышает ограничение виртуальной машины» - тогда мы собираемся выделить массив больше, чем размер виртуальной машины, при этом GC не требуется.JVM пытается сделать все возможное, и выбрасывание OOME не означает, что он скоро умрет.Кроме того, вызывать System.gc () для OOME, вызванного «Превышен лимит накладных расходов GC», вообще не имеет смысла - это сделает ситуацию еще хуже.

...