4

Я пытался исследовать java.lang.OutOfMemoryError: GC limit exceeded, которое происходит при высокой нагрузке нашего веб-приложения, размещенного в котом. Размер кучи был установлен в 8 ГБ (-Xms2048m -Xmx8192m)затмение анализатор памяти видит небольшую часть (363,2MB) всей кучи отвала (8GB)

В какой-то момент наше приложение перестает реагировать из-за накладных расходов GC. В журналах я видел, что Full GC происходит несколько раз подряд. Поэтому я взял кучу кучи со следующей командой (jmap -F -dump:format=b,file=/root/dump2.hprof 4963). Файл, содержащий дамп, имел размер 9 ГБ. После сброса дампа (приложение замораживалось около 45 минут), несколько полных ГК происходили до того, как был выброшен OutOfMemoryError.

Вот пример журнала ГК активности

[Full GC [PSYoungGen: 932096K->875513K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6467961K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 12.3954040 secs] [Times: user=47.60 sys=0.43, real=12.39 secs] 
[Full GC [PSYoungGen: 932096K->890562K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6483009K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 12.6131900 secs] [Times: user=48.45 sys=0.49, real=12.61 secs] 
[Full GC [PSYoungGen: 932096K->895268K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6487715K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 12.9488670 secs] [Times: user=49.61 sys=0.46, real=12.95 secs] 

Heap 
PSYoungGen  total 1864128K, used 896698K [0x0000000755560000, 0x0000000800000000, 0x0000000800000000) 
    eden space 932096K, 96% used [0x0000000755560000,0x000000078c10e8a8,0x000000078e3a0000) 
    from space 932032K, 0% used [0x000000078e3a0000,0x000000078e3a0000,0x00000007c71d0000) 
    to space 932032K, 0% used [0x00000007c71d0000,0x00000007c71d0000,0x0000000800000000) 
ParOldGen  total 5592448K, used 5592447K [0x0000000600000000, 0x0000000755560000, 0x0000000755560000) 
    object space 5592448K, 99% used [0x0000000600000000,0x000000075555ff30,0x0000000755560000) 
PSPermGen  total 262144K, used 112285K [0x00000005e0000000, 0x00000005f0000000, 0x0000000600000000) 
    object space 262144K, 42% used [0x00000005e0000000,0x00000005e6da7530,0x00000005f0000000) 

heap dump is taken (ca 45minutes freeze) 
[Full GC [PSYoungGen: 932096K->903362K(1864128K)] [ParOldGen: 5592447K->5592447K(5592448K)] 6524543K->6495810K(7456576K) [PSPermGen: 112285K->112285K(262144K)], 2883.9864390 secs] [Times: user=49.41 sys=0.47, real=2884.17 secs] 
[Full GC [PSYoungGen: 932096K->897728K(1864128K)] [ParOldGen: 5592447K->5592444K(5592448K)] 6524543K->6490173K(7456576K) [PSPermGen: 112288K->112288K(262144K)], 13.3092680 secs] [Times: user=50.75 sys=0.40, real=13.31 secs] 

Для анализа дампа кучи я открыл ее в затмении анализатора памяти (MAT). К сожалению, MAT показывает, что размер кучи составил 363,2 МБ (на вкладке «Обзор» или вкладке «Сведения о кучи»), тогда как в соответствии с GC-журналами куча была заполнена до 6467961K (6.4G). Недостижимые объекты Гистограмма показывает в общей сложности 75 511 736 (75 МБ). Гистограмма также подтвердила, что общая неглубокая куча была 380 837 136 (363,2 МБ)

Мой вопрос: почему MAT не отображает все объекты из дампа кучи, если GC не может вернуть память?

env details: 
Eclipse Memory Analyzer Version 1.2.1 
heap dump taken on 
java version "1.7.0_13" 
Java(TM) SE Runtime Environment (build 1.7.0_13-b20) 
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode) 

Вот скриншоты импортного дампа кучи в МХТ:

ответ

0

Это обычное поведение МПТ при сборе кучу дамп таких большая куча. Я часто собираю кучи кучи в 8 Гбайт кучи и обычно получаю профиль MAT, показывающий ~ 1GB живых объектов.

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

Далее см эту ссылку - MAT Does Not Show the Complete Heap:

Symptom: When monitoring the memory usage interactively, the used heap size is much bigger than what MAT reports.

During the index creation, the Memory Analyzer removes unreachable objects because the various garbage collector algorithms tend to leave some garbage behind (if the object is too small, moving and re-assigning addresses is to expensive). This should, however, be no more than 3 to 4 percent. If you want to know what objects are removed, enable debug output as explained here: MemoryAnalyzer/FAQ#Enable_Debug_Output

0

На самом деле я не рекомендую использовать утилиту jmap при устранении неполадок java.lang.OutOfMemoryError: GC limit exceeded проблемы. Я видел проблемы с этим подходом, в то время как JVM уничтожается (избыточное количество основных коллекций).

Пожалуйста, попробуйте следующий подход вместо и посмотреть, если вы получите лучшие результаты от процесса & анализа MAT синтаксического анализа:

  • Добавьте следующий параметр виртуальной машины Java HotSpot -XX: + HeapDumpOnOutOfMemoryError
  • Репликация проблемы снова и дождитесь события OOM. Генерация дампа кучи должна быть намного быстрее, что увеличит ценность и достоверность данных.
  • Виртуальная машина Java будет генерировать JVM Heap Dump (формат HPROF) после события OOM.
  • Загрузите снова кучу JVM кучи в MAT и посмотрите, получаете ли вы лучшие результаты, например. больший размер кучи.

Привет, Р-Н

+0

Я столкнулся с ситуацией, когда мы использовали выше флаг -XX: + HeapDumpOnOutOfMemoryError для создания дампа кучи, и он не сгенерировал кучу кучи, когда мы столкнулись с java.lang.OutOfMemoryError: предел GC превысил проблему, так как продолжает вызовы GC вызвало освобождение памяти, и оно запустило использование ЦП на более высокий уровень, и сервер не ответил, поэтому сервер сработал до запуска кучи кучи. пришлось использовать утилиту jmap и получить дамп кучи, когда использование памяти превышает 98%, что на самом деле не дало нам получить точный снимок во время OOM –

6

МАТ не отображает объекты, недоступные по умолчанию.

Вы можете включить эту опцию, выбрав Настройки -> Анализатор памяти -> Сохранить недоступные объекты. Загрузите кучу снова, когда опция включена.

Он отобразит полную кучу после включения опции. Даже я был в такой ситуации и не мог получить много информации в Интернете, и мой менеджер показал мне вариант. Надеюсь, это поможет.

+0

Хорошее предложение. Это также помогло мне найти ошибки в Apache PoI –

+0

@AndrewCarr я пытался, но не работал для меня. – Vipin

0

Мы нашли ошибку в МХТ недавно, где он будет видеть только подмножество кучи: https://bugs.eclipse.org/bugs/show_bug.cgi?id=404679#c3

Проблема заключалась в том, что JVM написал одну запись HEAP_DUMP, которая была более чем 4 Гб и, следовательно, длину в заголовке завернуты.

Какая версия MAT работает? Попробуйте более новую сборку.