Эта статья подготовлена технической командой OPPO Internet, укажите автора для перепечатки. В то же время приглашаем обратить внимание на нашу общедоступную учетную запись: OPPO_tech, чтобы поделиться с вами передовыми интернет-технологиями и деятельностью OPPO.
В этой статье не обсуждаются базовая структура данных и алгоритм G1, но вкратце представлен процесс G1 из поведения G1 GC.
Garbage-First Garbage Collector Судя по описанию на официальном сайте
G1 is a generational, incremental, parallel, mostly concurrent, stop-the-world, and evacuating garbage collector which monitors pause-time goals in each of the stop-the-world pauses. Similar to other collectors, G1 splits the heap into (virtual) young and old generations. Space-reclamation efforts concentrate on the young generation where it is most efficient to do so, with occasional space-reclamation in the old generation.
Несколько ключевых моментов можно выделить жирным шрифтом из введения
- Поколение
- параллелизм
- STW
- Сосредоточьтесь на целях времени паузы на каждом этапе STW
- Переработка в основном сосредоточена на наиболее работоспособном молодом поколении, а старое поколение встречается реже.
В G1 для повышения пропускной способности некоторые операции всегда (STW) останавливают мир. Другие являются долгосрочными, например глобальная маркировка, которая требует, чтобы операции с полной кучей выполнялись одновременно с приложением. Чтобы максимально сократить STW высвобождения пространства, G1 выполняет высвобождение пространства шаг за шагом параллельно. G1 строит модель прогнозирования приостановки, отслеживая информацию о предыдущем поведении приложения и приостановке сборки мусора. Он использует эту информацию для того, что он может делать во время паузы. Например, G1 сначала очищает наиболее эффективные регионы (то есть регионы, наиболее заполненные мусором, отсюда и название «сначала мусор»).
куча
G1 делит кучу на n областей одинакового размера.
- E - район Эдема
- S - выжившая область
- O - старый регион
- H огромен (старое поколение может быть огромным, видно, что оно может охватывать несколько последовательных регионов. Он напрямую назначается старому поколению, чтобы предотвратить повторное копирование и перемещение)
Параметры включены после Java 9
Начиная с Java9 введен единый журнал, то есть параметр Xlog. Ниже приведены рекомендуемые параметры GCLog:
-Xlog:gc*:file=your.log:tags,time,uptime,level:filecount=5,filesize=100m
GC фаза G1
Мы понимаем, что основные шаги в настройке
- Мера собирает соответствующую диагностическую информацию (например, сбор подробной информации gclog, в большинстве случаев подходит информация об уровне журнала по умолчанию).
- Поймите, поймите, что произошло
- Тюнинг тюнинг
Только поняв, что происходит внутри GC, можно соответствующим образом скорректировать его.
Давайте воспользуемся обычными журналами сборщика мусора, чтобы понять, что делает сборщик мусора тремя способами.
Young Only Phase
Сначала используйте картинку, чтобы просто понять процесс Young GC.
- Процесс сборки мусора выглядит следующим образом: Распределено->Эдем, Эдем->выживший, выживший->выживший, выживший->старый, выживший->выживший
- Как видите, есть Эдем, Выживший, Старый и Свободный регион.
- Апельсин - живой объект
- G1 скопирует оранжевый объект в свободную область.
- Когда копирование будет завершено, свободный регион будет переведен в регион выжившего, а предыдущий Эдем будет освобожден.
- Если Young gc, потратьте много времени
- Обычно большинство объектов в Юнге не живут очень долго.
- Если это правило не соблюдается (большинство объектов в Юнге долго не живут), возможно, вам придется скорректировать коэффициент Юнга. чтобы сократить время копирования объектов Young.
-
-XX:G1NewSizePercent
(по умолчанию: 5) Минимальное значение молодого региона -
-XX:G1MaxNewSizePercent
(по умолчанию: 60) Максимальное значение молодого региона
-
Mixed gc Phase
- Смешанный gc выберет все молодые регионы + несколько старых регионов с высоким доходом.
- Точно так же восстановленная область становится свободной областью.
- Из приведенного выше рисунка видно, что смешанный сборщик мусора может перерабатывать только часть старого.
- Как G1 выбирает, какие регионы перерабатывать?
-
-XX:G1MaxNewSizePercent
Подружитесь с молодым -
-XX:MixedGCCountTarget
ассоциируется со старым
-
-
-XX:MixedGCCountTarget
Значение по умолчанию — 8, что означает, что все старые регионы должны быть восстановлены в течение 8 раз.- Другими словами, если у вас есть 800 старых регионов, то смешанный сборщик мусора будет восстанавливать до 100 старых регионов за раз.
- G1 также можно настроить так, чтобы он не выполнял столько работы, то есть меньше перерабатывал, тратил память кучи и приводил к большему использованию кучи.
-
-XX:G1MixedGCLiveThresholdPercent
(по умолчанию: 85) может увеличить использование кучи -
-XX:G1HeapWastePercent
(по умолчанию: 5) Если восстанавливаемый меньше этого значения, то Mixed gc не будет запущен.
-
Full gc Phase
- Полный gc не должен происходить
Давайте сначала посмотрим на цикл GC
G1 состоит из двух этапов, он будет перемещаться между этими двумя этапами, а именно только для молодых, Space Reclamation.
- Young-only содержит серию gcs, которые постепенно заполняют старый gen.
- Space Reclamation G1 будет постепенно восстанавливать пространство старого поколения, а также обрабатывать молодой регион.
Изображение взято из описания цикла сборки мусора в оракуле, а сплошные кружки обозначают паузу сборки мусора.
- Синий только для молодых
- Желтый отмечает паузу в процессе
- Красный Смешанный gc пауза
После нескольких gcs коэффициент занятости объекта старого поколения превышаетInitiatingHeapOccupancyPercent
, gc перейдет к подготовке параллельной маркировки (одновременной маркировке).
- G1 ищет живые объекты (объекты со ссылками) в каждой коллекции Янга.
- G1 одновременно находит живые объекты в старом регионе
- называется параллельной маркировкой
- может занять много времени
- Не останавливает приложения Java
- G1 не может быть собран мусором без справочной информации о живых объектах
- Смешанный gc зависит от одновременной отметки
Возвращаясь к полной сборке мусора, из приведенного выше простого анализа делается вывод, что для полной сборки недостаточно свободных областей.Если куча достаточно велика, смешанная сборка мусора не восстанавливает достаточно старых областей, или параллельная метка не может быть завершено вовремя, это может привести к полной сборке мусора.
журнал сборщика мусора
[gc,start ] GC(78) Pause Young (Normal) (G1 Evacuation Pause)
[gc,task ] GC(78) Using 10 workers of 10 for evacuation
[gc,phases ] GC(78) Pre Evacuate Collection Set: 3.2ms
[gc,phases ] GC(78) Evacuate Collection Set: 28.8ms
[gc,phases ] GC(78) Post Evacuate Collection Set: 1.8ms
[gc,phases ] GC(78) Other: 1.1ms
[gc,heap ] GC(78) Eden regions: 538->0(871)
[gc,heap ] GC(78) Survivor regions: 69->33(76)
[gc,heap ] GC(78) Old regions: 1041->1077
[gc,heap ] GC(78) Humongous regions: 3->1
[gc,metaspace ] GC(78) Metaspace: 71777K->71777K(1114112K)
[gc ] GC(78) Pause Young (Normal) (G1 Evacuation Pause) 3300M->2220M(6144M) 34.907ms
[gc,cpu ] GC(78) User=0.24s Sys=0.05s Real=0.04s
[gc,start ] GC(79) Pause Young (Concurrent Start) (G1 Humongous Allocation)
[gc,task ] GC(79) Using 10 workers of 10 for evacuation
[gc,phases ] GC(79) Pre Evacuate Collection Set: 0.2ms
[gc,phases ] GC(79) Evacuate Collection Set: 22.3ms
[gc,phases ] GC(79) Post Evacuate Collection Set: 0.9ms
[gc,phases ] GC(79) Other: 1.8ms
[gc,heap ] GC(79) Eden regions: 569->0(656)
[gc,heap ] GC(79) Survivor regions: 33->55(113)
[gc,heap ] GC(79) Old regions: 1077->1077
[gc,heap ] GC(79) Humongous regions: 1->1
[gc,metaspace ] GC(79) Metaspace: 71780K->71780K(1114112K)
[gc ] GC(79) Pause Young (Concurrent Start) (G1 Humongous Allocation) 3357M->2264M(6144M) 25.305ms
[gc,cpu ] GC(79) User=0.21s Sys=0.00s Real=0.03s
[gc ] GC(80) Concurrent Cycle
[gc,marking ] GC(80) Concurrent Clear Claimed Marks
[gc,marking ] GC(80) Concurrent Clear Claimed Marks 0.147ms
[gc,marking ] GC(80) Concurrent Scan Root Regions
[gc,marking ] GC(80) Concurrent Scan Root Regions 16.125ms
[gc,marking ] GC(80) Concurrent Mark (373.358s)
[gc,marking ] GC(80) Concurrent Mark From Roots
[gc,task ] GC(80) Using 4 workers of 4 for marking
[gc,marking ] GC(80) Concurrent Mark From Roots 57.029ms
[gc,marking ] GC(80) Concurrent Preclean
[gc,marking ] GC(80) Concurrent Preclean 0.454ms
[gc,marking ] GC(80) Concurrent Mark (373.358s, 373.415s) 57.548ms
[gc,start ] GC(80) Pause Remark
[gc,stringtable] GC(80) Cleaned string and symbol table, strings: 36361 processed, 315 removed, symbols: 192117 processed, 500 removed
[gc ] GC(80) Pause Remark 2326M->956M(6144M) 14.454ms
[gc,cpu ] GC(80) User=0.08s Sys=0.03s Real=0.02s
[gc,marking ] GC(80) Concurrent Rebuild Remembered Sets
[gc,marking ] GC(80) Concurrent Rebuild Remembered Sets 38.843ms
[gc,start ] GC(80) Pause Cleanup
[gc ] GC(80) Pause Cleanup 974M->974M(6144M) 0.660ms
[gc,cpu ] GC(80) User=0.00s Sys=0.00s Real=0.00s
[gc,marking ] GC(80) Concurrent Cleanup for Next Mark
[gc,marking ] GC(80) Concurrent Cleanup for Next Mark 16.673ms
[gc ] GC(80) Concurrent Cycle 146.748ms
[gc,start ] GC(81) Pause Young (Prepare Mixed) (G1 Evacuation Pause)
[gc,task ] GC(81) Using 10 workers of 10 for evacuation
[gc,mmu ] GC(81) MMU target violated: 61.0ms (60.0ms/61.0ms)
[gc,phases ] GC(81) Pre Evacuate Collection Set: 0.1ms
[gc,phases ] GC(81) Evacuate Collection Set: 76.8ms
[gc,phases ] GC(81) Post Evacuate Collection Set: 0.9ms
[gc,phases ] GC(81) Other: 1.1ms
[gc,heap ] GC(81) Eden regions: 211->0(136)
[gc,heap ] GC(81) Survivor regions: 55->17(34)
[gc,heap ] GC(81) Old regions: 392->443
[gc,heap ] GC(81) Humongous regions: 3->1
[gc,metaspace ] GC(81) Metaspace: 71780K->71780K(1114112K)
[gc ] GC(81) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 1320M->919M(6144M) 78.857ms
[gc,cpu ] GC(81) User=0.41s Sys=0.37s Real=0.08s
[gc,start ] GC(82) Pause Young (Mixed) (G1 Evacuation Pause)
[gc,task ] GC(82) Using 10 workers of 10 for evacuation
[gc,phases ] GC(82) Pre Evacuate Collection Set: 0.1ms
[gc,phases ] GC(82) Evacuate Collection Set: 22.1ms
[gc,phases ] GC(82) Post Evacuate Collection Set: 0.8ms
[gc,phases ] GC(82) Other: 0.9ms
[gc,heap ] GC(82) Eden regions: 136->0(142)
[gc,heap ] GC(82) Survivor regions: 17->11(20)
[gc,heap ] GC(82) Old regions: 443->367
[gc,heap ] GC(82) Humongous regions: 1->1
[gc,metaspace ] GC(82) Metaspace: 71780K->71780K(1114112K)
[gc ] GC(82) Pause Young (Mixed) (G1 Evacuation Pause) 1191M->757M(6144M) 23.970ms
[gc,cpu ] GC(82) User=0.15s Sys=0.08s Real=0.03s
[gc,start ] GC(83) Pause Young (Mixed) (G1 Evacuation Pause)
[gc,task ] GC(83) Using 10 workers of 10 for evacuation
[gc,phases ] GC(83) Pre Evacuate Collection Set: 0.1ms
[gc,phases ] GC(83) Evacuate Collection Set: 5.0ms
[gc,phases ] GC(83) Post Evacuate Collection Set: 0.8ms
[gc,phases ] GC(83) Other: 1.1ms
[gc,heap ] GC(83) Eden regions: 142->0(783)
[gc,heap ] GC(83) Survivor regions: 11->10(20)
[gc,heap ] GC(83) Old regions: 367->294
[gc,heap ] GC(83) Humongous regions: 1->1
[gc,metaspace ] GC(83) Metaspace: 71780K->71780K(1114112K)
Выше приведен журнал нескольких последовательных GC, который можно просмотреть в сравнении с циклом GC. Для облегчения набора теги, связанные со временем, были упрощены.
- GC(78) — обычная молодая гк, и информация в ней имеет различные региональные изменения
- Вот краткий рассказ об обращении с огромными объектами.
- огромные объекты обрабатываются особым образом в G1, G1 только решает, живы ли они, восстанавливает пространство, которое они занимают, и никогда не перемещает их
- Стадия «Только для молодых», огромные области могут быть переработаны
- Space-Reclamation, огромные регионы могут быть переработаны
- GC(79) начинает входить в параллельную фазу
- Сборщик мусора (80) завершает очистку, после чего следует сборка мусора с помощью команды Подготовить смешанный сборщик мусора (81), что соответствует сплошному синему кругу справа от пунктирной линии с точкой.
- После GC(82) наступает фаза освобождения пространства, на которой будет выполняться несколько смешанных GC.
По логу можно просто посмотреть время, потраченное на каждый шаг и сборку мусора в соответствующей области.В сочетании с параметрами GC можно найти проблему и соответствующим образом настроить параметры.
Пропускная способность и низкая задержка не могут совмещать одновременно. Низкая задержка означает, что GC будет работать чаще, что относительно займет ресурсы приложения и снизит пропускную способность. Если требуется высокая пропускная способность, то работа GC сократится, наоборот, с каждым разом будет собираться больше мусора, увеличится время паузы и увеличится задержка.
-XX:MaxGCPauseMillis
G1 попытается уложиться в целевое время, установленное этим параметром, и этот параметр может сбалансировать пропускную способность и задержку, требуемые приложением.
наконец
Основными справочными материалами в этой статье являются официальные статьи и документы, а сложные внутренние реализации не затрагиваются.Помимо улучшений G1, в новой версии JDK также появилось несколько новых.
- Epsilon GC (no-op), сборщик мусора без операций, просто не собирает мусор, и при выделении места в куче jvm останавливается.
- zgc Сборщик мусора большой кучи, пауза не более 10 мс, поддержка кучи T-уровня
- Shenandoah также является сборщиком мусора с малой задержкой.
Из-за плохого знания неизбежно будут опечатки, добро пожаловать на обсуждение.