ООМ может быть вызвано не нахождением достаточного количества непрерывной памяти? - PullRequest
0 голосов
/ 29 ноября 2011

Я запускаю некоторый код Java с -Xmx1024m, и в какой-то момент я получаю hprof из-за OOM.Hprof показывает только 320 МБ и дает мне трассировку стека:

 at java.util.Arrays.copyOfRange([CII)[C (Arrays.java:3209)
  at java.lang.String.<init>([CII)V (String.java:215)
  at java.lang.StringBuilder.toString()Ljava/lang/String; (StringBuilder.java:430)
  ...

Это происходит из большой строки, которую я копирую.

Я помню, что где-то читал (не могу найти), что произошлоэти случаи таковы:

  • процесс по-прежнему не использует 1 ГБ памяти, он намного ниже
  • , даже если объем кучи все еще ниже 1 ГБ, ему требуется некоторое количество памяти, а для copyOfRange()это должна быть непрерывная память, поэтому, даже если она еще не превышает лимит, она не может найти достаточно большой фрагмент памяти на хосте, она завершается с OOM.

Я пыталсяпоищите документацию по этому вопросу (copyOfRange() нужен блок непрерывной памяти), но не удалось найти какой-либо.

Другому возможному виновнику не хватило бы постоянной памяти.

Может ли кто-нибудь подтвердить или опровергнуть гипотезу непрерывной памяти?Любой указатель на какой-то документ тоже поможет.

1 Ответ

1 голос
/ 29 ноября 2011

Если вы используете параллельный сборщик меток, вы можете получить фрагментацию.однако для новых объектов, при условии, что есть достаточно места для молодого поколения, вам не нужно беспокоиться о фрагментации, поскольку свободное пространство Eden всегда непрерывно.

Во многих приложениях дается только небольшая часть кучимолодому поколению, так что если у вас есть фрагментированное пространство и вы создаете относительно небольшой объект (до 5% от максимального объема памяти), вы можете получить ошибку OutOfMemoryError.

Учитывая, что производительность будет очень низкойесли вы работаете близко к максимальному объему памяти, я бы посоветовал вам либо заставить ваше приложение использовать меньше памяти, либо увеличить максимум.Это также увеличивает размер вашего поколения.В качестве альтернативы вы можете установить -XX:NewSize=512m

...