Возможно ли получить OutOfMemoryError, потому что сборка мусора слишком медленная? - PullRequest
11 голосов
/ 04 января 2012

В java, возможно ли, что вы получите исключение OutOfMemoryError, даже если должно быть достаточно памяти, если сборщик мусора освободит больше памяти?Другими словами, если недостаточно памяти для выделения, будет ли принудительно запускаться gc перед выдачей ошибки OutOfMemoryError?

Спасибо.

Ответы [ 5 ]

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

Существует один случай, когда вы можете получить OOM, который не связан ни с кучей, ни с адресным пространством: это когда JVM решает, что GC требует слишком много времени для запуска.

См. здесь .

Другими словами, ответ на ваш первоначальный вопрос, а именно: «Если не хватает памяти для выделения, будет вынужден выполнить gc перед выдачей ошибки OutOfMemoryError», это да.

(из приведенной выше ссылки вы увидите, что для gc / исполняемого кода это соотношение составляет 98% / 2%, что уже очень высоко)

(примечание 2: это для JVM от Sun / Oracle, без идеи для других реализаций)

5 голосов
/ 04 января 2012

вы можете получить его, если GC тратит слишком много времени, пытаясь освободить память и не освобождая ее, выполняя это 'java.lang.OutOfMemoryError: Превышен лимит накладных расходов GC', см. этот вопрос ,

2 голосов
/ 04 января 2012

GC принудительно запускается до того, как выдается OutOfMemoryError.Если JVM реализует несколько разновидностей GC (например, «одновременный» или «частичный»), GC «Остановить мир» будет запущен до того, как JVM сдастся, поэтому были предприняты все возможные усилия, чтобы избежать ошибки.

Исключением является то, что, если GC многократно запускается и восстанавливает только минимальный объем памяти (и размер кучи не может быть увеличен в дальнейшем), он будет добавлен в полотенце, а не продолжит работу в режиме "сканирования".Теоретически, для этого случая немного увеличивающийся размер кучи позволил бы «хорошему» приложению работать нормально, но приложение, которое медленно жует кучу (что не является необычным), не получило бы выгоды от небольшого увеличения кучи и столкнулось бы стот же сбой только чуть позже.

[Следует отметить, что в случаях, когда GC работает слишком часто, увеличение размера кучи может значительно снизить издержки GC, , если ,приложение хорошо себя ведет и просто случайно работает вблизи предела кучи.(Конечно, увеличение размера кучи до уровня доступной оперативной памяти обычно замедляет работу приложения.)]

1 голос
/ 16 января 2013

Кажется, если вы напишите свой код, вы никогда не нажмете OOM. Потому что JVM запустит gc до того, как он достигнет OOM.

Так что, если вы нажмете OOM, скорее всего, ваш код получит утечку памяти. Проверьте это.

http://www.ibm.com/developerworks/library/j-leaks/

1 голос
/ 04 января 2012

GC будет обычно пытаться найти память до того, как будет выброшено OutOfMemoryError, но очень редко Я видел воспроизводимые примеры, когда сборщик мусора не совсем успевает, и вызов System.gc() предотвращает исключение.

Это скорее исключение (без каламбура), а не правило - вы должны почти никогда пытаться спровоцировать сборку мусора самостоятельно.

...