Ненужный полный GC со сборщиком мусора G1 в Java 8?

Мы заметили случайные полные GC со сборщиком мусора G1 с переполнением concurrent-mark. После того, как произойдет сброс параллельной метки для переполнения, это переполнение будет продолжаться на следующих фазах параллельной метки. В конце концов, это приводит к полной сборке мусора, поскольку одновременная метка больше не работает.

У нас есть четыре машины, на которых запущено одно и то же приложение на основе Apache Storm с одинаковым трафиком данных. Только одна из машин имеет этот опыт один раз в неделю.

Связано ли это с ошибкой: «G1 не расширяет стек маркировки, когда во время одновременной маркировки происходит переполнение стека меток» https://bugs.openjdk.java.net/browse/JDK-8065402

В соответствии с предложением на странице выше, мы удвоили число параллельных потоков с 4 до 8 и размер нашей кучи с 8 ГБ до 16 ГБ. Однако полный сборщик мусора все еще происходит, и единственное отличие состоит в том, что вхождения задерживаются.

Любые другие предложения?

Вот журнал GC:

Java HotSpot(TM) 64-Bit Server VM (25.65-b01) for linux-amd64 JRE(1.8.0_65b17), 
built on Oct  6 2015 17:16:12 by "java_re" with gcc 4.3.0 20080428 (Red Hat 4.3.0-8) 
Memory: 4k page, physical 529167668k(69283408k free), swap 33554424k(33552380k free) 
CommandLine flags: -XX:ConcGCThreads=8 -XX:G1ReservePercent=20 -XX:GCLogFileSize=104857600 
-XX:InitialHeapSize=17179869184 -XX:InitiatingHeapOccupancyPercent=45 -XX:MaxGCPauseMillis=100 
-XX:MaxHeapSize=17179869184 -XX:NumberOfGCLogFiles=10 -XX:ParallelGCThreads=30 
-XX:+PrintAdaptiveSizePolicy -XX:PrintFLSStatistics=2 -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC 
-XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:+UseGCLogFileRotation
...
...
2016-04-13T22:06:37.254-0400: 19839.175: [GC concurrent-root-region-scan-start]
2016-04-13T22:06:37.313-0400: 19839.234: [GC concurrent-root-region-scan-end, 0.0592966 secs]
2016-04-13T22:06:37.313-0400: 19839.234: [GC concurrent-mark-start]
2016-04-13T22:06:38.569-0400: 19840.490: [GC concurrent-mark-reset-for-overflow]
...
2016-04-13T22:06:42.810-0400: 19844.731: [GC concurrent-mark-reset-for-overflow]
...
2016-04-13T22:11:19.253-0400: 20121.175: [GC concurrent-mark-reset-for-overflow]
...
...
...
2016-04-14T01:58:17.254-0400: 33739.176: [GC concurrent-mark-reset-for-overflow]
...
2016-04-14T01:58:36.957-0400: 33758.878: [Full GC (Allocation Failure)

person Jeff    schedule 15.04.2016    source источник
comment
Прочтите эту статью: blogs.oracle.com/poonam/entry/understanding_g1_gc_logs :3.198: [GC concurrent-mark-reset-for-overflow] Это указывает на то, что стек глобальной маркировки заполнился и произошло переполнение стека. Параллельная маркировка обнаружила это переполнение и должна была сбросить структуры данных, чтобы снова начать маркировку.   -  person Ravindra babu    schedule 15.04.2016


Ответы (1)


Из блога оракула g1_gc:

GC concurrent-mark-reset-for-overflow : Это указывает на то, что глобальный стек маркировки заполнился и произошло переполнение стека. Параллельная маркировка обнаружила это переполнение и должна была сбросить структуры данных, чтобы снова начать маркировку.

Таким образом, увеличение -XX:MarkStackSize — это одна быстрая победа.

Несколько замечаний по параметрам вашей виртуальной машины:

  1. G1 GC — это адаптивный сборщик мусора со значениями по умолчанию, которые позволяют ему эффективно работать без изменений. Взгляните на страницу документации oracle на G1GC.
  2. Ключевые параметры для установки: -XX:MaxGCPauseMillis, -XX:G1HeapRegionSize,-XX:ParallelGCThreads=n, -XX:ConcGCThreads=n Оставьте все остальные значения по умолчанию.
  3. Если размер вашей кучи составляет 16 ГБ, идеальный размер региона должен быть 8 MB. Убедитесь, что вы поддерживаете 2048 регионов.
  4. Пересмотрите свою цель по времени паузы. -XX:MaxGCPauseMillis. Если 200ms нереально для кучи 16 ГБ, установите это значение соответствующим образом.
  5. Страница официальной документации рекомендует способ установки XX:ParallelGCThreads=n, -XX:ConcGCThreads=n в зависимости от количества ядер на вашем компьютере.

    -XX:ParallelGCThreads=n: устанавливает значение рабочих потоков STW. Устанавливает значение n равным количеству логических процессоров. Значение n совпадает с количеством логических процессоров до значения 8.

    -XX:ConcGCThreads=n: устанавливает количество параллельных нитей маркировки. Устанавливает n примерно равным 1/4 числа параллельных потоков сборки мусора (ParallelGCThreads).

  6. Пересмотрите параметры -XX:InitialHeapSize=17179869184 -XX:InitiatingHeapOccupancyPercent=45 -XX:G1ReservePercent=20. Оставьте для них значения по умолчанию, если у вас нет острой необходимости изменить их.

Посетите эту страницу, чтобы лучше понять журналы G1GC.

person Ravindra babu    schedule 15.04.2016
comment
Полный сборщик мусора после повторяющихся одновременных сбросов меток для переполнения (та же проблема, что и в вопросе) снова произошел на одной из четырех машин с новой настройкой добавления -XX:MarkStackSize=16M. выполнит обновление, если проблема будет решена после дальнейшего увеличения -XX:MarkStackSize. - person Jeff; 03.05.2016