Подтвердить что ты не робот

Обновление Java 6 25 Авария VM: недостаточная память

Для обновления этого вопроса - см. ниже.

Я испытываю (воспроизводимый, по крайней мере для меня) jvm crash (не OutOfMemoryError) (Сбой приложения - eclipse 3.6.2). Однако, глядя на журнал сбоев, я задаюсь вопросом:

#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 65544 bytes for Chunk::new
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.

Current thread (0x531d6000):  JavaThread "C2 CompilerThread1" daemon 
[_thread_in_native, id=7812, stack(0x53af0000,0x53bf0000)]

Stack: [0x53af0000,0x53bf0000],  sp=0x53bee860,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0x1484aa]
V  [jvm.dll+0x1434fc]
V  [jvm.dll+0x5e6fc]
V  [jvm.dll+0x5e993]
V  [jvm.dll+0x27a571]
V  [jvm.dll+0x258672]
V  [jvm.dll+0x25ed93]
V  [jvm.dll+0x260072]
V  [jvm.dll+0x24e59a]
V  [jvm.dll+0x47edd]
V  [jvm.dll+0x48a6f]
V  [jvm.dll+0x12dcd4]
V  [jvm.dll+0x155a0c]
C  [MSVCR71.dll+0xb381]
C  [kernel32.dll+0xb729]

Я использую 32-разрядный SP3 для Windows XP. У меня 4 ГБ оперативной памяти. Перед запуском приложения у меня было 2 ГБ бесплатно в соответствии с диспетчером задач (системный кеш + 1 ГБ, который также может быть освобожден). У меня определенно достаточно свободного ОЗУ.

С самого начала и до сбоя я записал статистику памяти jvm с помощью visualvm и jconsole. Я приобрел статистику потребления памяти до последних моментов перед сбоем.

Статистика показывает следующие распределенные размеры памяти:

  • HeapSize: 751 МБ (используется 248 МБ)
  • Non-HeapSize (PermGen и CodeCache): 150 МБ (используется 95 МБ)
  • Размер областей управления памятью (Edenspace, Old-gen и т.д.): 350 МБ
  • Размеры стека потоков: 17 МБ (согласно oracle и из-за того, что работает 51 поток )

Я запускаю приложение (jre 6 update 25, server vm), используя параметры:

-XX:PermSize=128m
-XX:MaxPermSize=192m
-XX:ReservedCodeCacheSize=96m
-Xms500m
-Xmx1124m

Вопрос:

  • Почему авария jvm падает, когда на vm и ОС достаточно памяти?
    С приведенными выше настройками я думаю, что я не могу попасть в 32-битный лимит 2 ГБ (1124 МБ + 192 МБ + 96 МБ + стеки потоков и 2 ГБ). В любом другом случае (слишком большое выделение кучи) я предпочел бы ожидать OutOfMemoryError, чем авария jvm

Кто может помочь мне разобраться, что здесь происходит?

(Примечание. Я недавно обновил Eclipse 3.6.2 от Eclipse 3.4.2 и от Java 5 до Java 6. Я подозреваю, что существует связь между сбоями и этими изменениями, потому что я не видел их раньше)

UPDATE

Кажется, это ошибка jvm, представленная в Java 6 Update 25 и что-то связано с новым компилятором jit. См. Также эту запись в блоге. Согласно блогу, исправление этой ошибки должно быть частью следующего обновления java 6. В то же время во время сбоя я получил собственную трассировку стека. Я обновил приведенный выше журнал сбоев.

Предлагаемое обходное решение с использованием аргумента vm -XX:-DoEscapeAnalysis работает (по крайней мере, это заметно снижает вероятность сбоя)

4b9b3361

Ответ 1

Я наткнулся на подобную проблему на работе. Мы установили -Xmx65536M для нашего приложения, но все равно получали одинаковые ошибки. Самое смешное в том, что ошибки всегда происходили в то время, когда наше приложение действительно делало довольно легкие вычисления, относительно говоря, и, таким образом, нигде не было этого предела.

Мы нашли возможное решение проблемы в Интернете: http://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp, и это, казалось, решило нашу проблему. После снижения -Xmx до 50G у нас не было ни одной из этих проблем.

Что на самом деле происходит в этом случае, нам все еще неясно.

Ответ 2

JVM имеет свои собственные ограничения, которые остановят его задолго до того, как он ударит по физическим или виртуальным ограничениям памяти. То, что вам нужно настроить, - это размер кучи, который с другим одним из флагов -X. (Я думаю, что это что-то творческое, как -XHeapSizeLimit, но я проверю через секунду.)

Здесь мы идем:

-Xmsn Укажите начальный размер пула распределения памяти в байтах. Это значение должно быть кратно 1024 более 1 МБ. Приложите букву k или K, чтобы указать килобайты, или m или M для указания мегабайт. По умолчанию значение равно 2 МБ. Примеры:

   -Xms6291456
   -Xms6144k
   -Xms6m

-Xmxn Укажите максимальный размер пула распределения памяти в байтах. Это значение должно быть кратно 1024 более 2 МБ. Приложите букву k или K, чтобы указать килобайты, или m или M для указания мегабайт. По умолчанию значение составляет 64 МБ. Примеры:

   -Xmx83886080
   -Xmx81920k
   -Xmx80m