Анализ всего процесса сборщика мусора JVM G1 (Garbage-First Garbage Collector)

JVM

G1Принцип построения сборщика мусора — «Сначала мусор», а цель — свести к минимуму паузы, вызванные обработкой очень больших куч (более 4 ГБ).

следовательно,G1не ждет, пока закончится память (например,Serialсерийный коллекционер,ParallelПараллельный коллектор ) заканчивается (CMS), но внутри используется эвристический алгоритм для поиска разделов с высокой доходностью сбора в старом возрасте (Region) собирать.

в то же времяG1может быть установлен пользователемSTW(Stop-The-World) Целевое время паузы (приоритет времени отклика) автоматически регулирует размер молодого поколения и общей кучи.Чем короче время паузы, тем меньше может быть пространство молодого поколения и больше общее пространство кучи .

G1относительноCMSБолее очевидным преимуществом является то, что скорость генерации фрагментации памяти значительно снижается.

G1Его можно использовать в JDK7u4 и выше, начиная с JDK9,G1является сборщиком мусора по умолчанию, а неCMS.

Алгоритм G1

Алгоритм: Трехцветный маркер + SATB

Особенности G1

  • Сборщик мусора для серверных приложений
  • Параллелизм и параллелизм: G1 может в полной мере использовать преимущества нескольких ЦП,многоядерныйСреда использует несколько ЦП или ядер ЦП для сокращенияSTW(Stop-The-World) Время паузы.
  • Коллекция поколений: G1 физически не является генерацией поколений, но логически по-прежнему имеет концепцию генерации поколений.
  • Консолидация пространства: фрагментация пространства памяти не будет создаваться.После сбора он может обеспечить обычную доступную память и быстрее организовать свободное пространство.
  • Предсказуемые зависания (можно спланировать, чтобы избежать полной сборки мусора во всей куче Java)
  • Подходит для сценариев, где не требуется высокая пропускная способность
  • Структура памяти кучи JAVA сильно отличается от других сборщиков, она делит всю кучу JAVA на несколько независимых областей или разделов одинакового размера (Region).
  • В сборщике G1 виртуальная машина используетRemembered Setчтобы избежать полного сканирования кучи.

Модель памяти G1

концепция раздела

Традиционный сборщик GC делит непрерывное пространство памяти на новое поколение, старое поколение и постоянное поколение (JDK 8 удаляет постоянное поколение и вводит метапространство Metaspace),

Особенность этого деления в том, что адреса хранения (логические адреса, то же ниже) каждого поколения непрерывны. Как показано ниже:

Адреса хранения каждого поколения G1 являются прерывистыми, и каждое поколение использует n прерывистых адресов одинакового размера.Region, каждыйRegionЗанимает непрерывный адрес виртуальной памяти.

Region(регион, раздел)

G1 использует разделы (Region), разделить все пространство кучи на несколько областей памяти одинакового размера, и каждый раз при выделении пространства объекта память будет использоваться сегмент за сегментом.

Хотя концепции нового поколения и старого поколения все еще сохраняются, новое поколение и старое поколение больше не разделены физически, они все являются частьюRegion(не обязательно должны быть смежными) коллекции.

Следовательно, при использовании кучи G1 не требует, чтобы хранение объектов было физически непрерывным, если оно логически непрерывно;

каждый разделRegionОн также не обслуживает определенное поколение детерминистически и может переключаться между молодым и старым поколениями по мере необходимости.

При запуске можно передать параметры-XX:G1HeapRegionSize=nМожно указать размер раздела (1 МБ~32 МБ и должен быть степенью 2).По умолчанию вся куча разделена на 2048 разделов.

Card(карта)

в каждом разделеRegionВнутреннее пространство разделено на несколько карт (Cards) размером 512 байт, которые определяют минимально доступную гранулярность кучи памяти.

Все разделыRegionкарты будут записаны в глобальную таблицу карт (Global Card Table)середина.

Выделенный объект занимает несколько карт, которые физически следуют друг за другом.

При поиске разделаRegionКогда найдена ссылка на внутренний объект, указанный объект можно найти через карточку записи (см.RSet).

При каждом освобождении памяти обрабатываются карты в указанном разделе.

Heap(куча)

G1 также может пройти-Xms/-Xmxуказать размер кучи.

Когда происходит сбор молодого поколения (YGC) или смешанная коллекция (Mixed GC), автоматически регулировать размер пространства кучи, вычисляя соотношение затрат времени на сборщик мусора и приложение.

Если частота GC слишком высока, частота GC снижается за счет увеличения размера кучи, и соответственно уменьшается время, занимаемое GC;

целевой параметр-XX:GCTimeRatioТо есть отношение затрат времени GC на приложение, G1 по умолчанию равно 12 (JDK7, 8 равно 99, JDK11+ начинает равняться 12), а CMS по умолчанию равно 99, потому что принцип разработки CMS заключается в том, чтобы тратить как можно меньше времени на ГК, насколько это возможно.

Кроме того, когда места недостаточно, например, при выделении пространства объекта или сбое передачи, G1 сначала попытается увеличить пространство кучи, а если расширение не удастся, он инициирует гарантированныйFull GC.

Full GCПосле этого результат расчета размера кучи также будет корректировать пространство кучи.

Концепция генерации

Generation(поколение)

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

Хотя секционирование делает выделение памяти более не требующим компактного пространства памяти, G1 по-прежнему использует идею генерации.

Подобно другим сборщикам мусора, G1 логически делит память на молодое поколение и старое поколение, а молодое поколение далее делится на пространство Эдема и пространство выжившего.

Однако пространство молодого поколения не фиксировано.Когда существующий раздел молодого поколения заполнен, JVM выделит новый свободный раздел для пространства молодого поколения.

Вся память молодого поколения будет в начальном пространстве-XX:NewSizeс максимальным пространством-XX:MaxNewSizeдинамические изменения между ними, и определяется параметром целевого времени паузы-XX:MaxGCPauseMillis, размер, который нужно увеличить и уменьшить, и запомненный набор разделов (RSet) рассчитывается.

Конечно, G1 все еще может установить фиксированный размер молодого поколения (параметр-XX:NewRatio,-Xmn), но приостанавливать цель при этом было бы бессмысленно.

#####Local allocation buffer (LAB) (локальный буфер распределения) Стоит отметить, что благодаря идее разделов каждый поток может «претендовать» на разделRegionИспользуется для локального выделения памяти потока, независимо от того, является ли раздел непрерывным.

Таким образом, каждый поток приложения и поток GC будут использовать раздел независимо, тем самым сокращая время синхронизации и повышая эффективность GC.Regionназывается локальным буфером выделения (LAB).

  • локальный буфер потока приложенияTLAB: Поток приложения может монополизировать локальный буфер (TLAB) для создания объектов, и большинство из них попадет в область Эдема (за исключением гигантских объектов или сбоев выделения), поэтому раздел TLAB принадлежит пространству Эдема;
  • Локальный буфер потока GCGCLAB: 每次垃圾收集时,每个GC线程同样可以独占一个本地缓冲区(GCLAB) используется для переноса объектов, и каждая коллекция копирует объект в пространство Suvivor или в старое пространство;
  • Продвигать локальный буферPLAB: Для объектов, перемещенных из пространства Eden/Survivor в пространство Survivor/Old Generation, также существует локальный буфер, эксклюзивный для GC для работы, который называется локальным буфером продвижения (PLAB).

модель раздела

Humongous Object(гигантский объект)

размер, который достигает или превышает размер разделаRegionБолее 50% объектов называются гигантскими объектами (Humongous Object). Гигантский объект будет монополизировать один или несколько смежных разделов, первый из которых помечен как начальный гигант (StartsHumongous), смежные смежные разделы помечаются как смежные гигантские (ContinuesHumongous).Humongous ObjectИмеет следующие характеристики:

  • Humongous ObjectОн напрямую относится к старому поколению, предотвращая повторное копирование и перемещение.

Когда потоки выделяют место для jumbo, вы не можете простоTLABВыделите, потому что гигантские объекты дорого перемещать, и возможно, что один раздел не будет содержать гигантские объекты. Поэтому гигантские объекты выделяются непосредственно в старом поколении, а занимаемое смежное пространство называется гигантским разделом (Humongous Region).

  • Humongous ObjectсуществуетYGCсцена,Global Concurrent MarkingсценаCleanupа такжеFGCФазовая переработка.

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

  • в распределенииHumongous ObjectПрежде чем проверять, не превышен ли начальный процент заполнения кучи (по параметру-XX:InitiatingHeapOccupancyPercentконтроль) и порог маркировки. Если он превышает, запустите параллельный цикл сбораConcurrent Marking Cycle, чтобы переработать раньше, предотвратитьEvacuation Failureа такжеFull GC.
RSet(Remember Set, заученная коллекция)

Как в последовательных, так и в параллельных сборщиках сборщик мусора сканирует всю кучу, чтобы определить, находится ли объект на доступном пути.

Однако, чтобы избежать G1STWцелая кучаHeapсканирование, в каждом разделеRegionзаписал запоминаемый набор (RSet), который внутренне похож на обратный указатель, запись ссылается на разделRegionкарточка внутреннего объектаCardиндекс чего-либо.

когда раздел должен быть восстановленRegionВ то же время путем сканирования набора RSet раздела определяется, живы ли объекты в указанном разделе, а затем определяется выживание объектов в этом разделе.

На самом деле, не все ссылки должны быть записаны вRSet, если разделRegionопределил, что сканирование требуется, то нетRSetЭталонное отношение также может быть получено без упущения.

то ссылка происходит из этого разделаRegionобъект, конечно, не попадая вRSetсередина;

В то же время G1 GC каждый раз будет собирать молодое поколение целиком, поэтому ссылки на объекты из молодого поколения не нужно хранить в молодом поколении.RSetЗаписывать.

Наконец только раздел старостиRegionМогут быть записи RSet, и эти разделы называются областью-владельцем RSet.

Per Region Table (PRT)

RSetиспользуется внутриPer Region Table(PRT) раздел записиRegionцитаты. из-заRSetзаписей, занимающих разделыRegionпространство, если раздел очень "популярный", тоRSetЗанятое пространство будет увеличиваться, уменьшая перегородкуRegionдоступного пространства. G1 отреагировал на эту проблему изменениямиRSetплотность пути, вPRTСсылки будут записываться в трех режимах:

  • Редко: карты, которые напрямую записывают упомянутые объекты.Cardиндекс чего-либо
  • Мелкозернистый: запись разделов ссылочных объектовRegionиндекс чего-либо
  • Крупнозернистый: только ссылки на записи, каждый раздел соответствует одному биту

Из вышеизложенного видно, что крупнозернистаяPRTПросто запишите количество упоминаний, вам нужно пройти всю кучуHeapСканирование является самым медленным, чтобы найти все ссылки.

CSet(Collection Set, коллекционный набор)

коллекция коллекция (CSet) представляет собой последовательность целевых разделов, которые освобождаются при каждой паузе сборки мусора.Region.

Во время любой паузы сбораCSetВсе разделы будут освобождены, а объекты, оставшиеся внутри, будут перемещены в выделенные свободные разделы.

Поэтому, будь то коллекция молодого поколения или смешанная коллекция, механизм работы одинаков.

Коллекция молодого поколения (YGC)изCSetРазмещаются только разделы молодого поколения, а смешанные коллекции (Mixed GC) будет использовать эвристический алгоритм, чтобы отфильтровать разделы с наибольшим возвратом восстановления из разделов-кандидатов на восстановление в старом возрасте и добавить их вCSetсередина.

  • раздел кандидата по старостиCSetУсловия доступа, которые могут превышать порог активности-XX:G1MixedGCLiveThresholdPercent(по умолчанию 85%) настроен на перехват объектов с огромными затратами на переработку;

  • В то же время каждая смешанная коллекция может содержать разделы-кандидаты старого поколения, которые можно определить поCSetПроцент от общего размера кучи-XX:G1OldCSetRegionThresholdPercent(по умолчанию 10%) Установите верхний предел количества.

Из вышеизложенного видно, что коллекция G1 основана наCSetОперативная коллекция молодого поколения (YGC) и смешанная коллекция (Mixed GC) существенно не отличаются, самая большая разница заключается в условиях срабатывания для двух коллекций.

коллекция молодого поколенияCSet of Young Collection

После того, как поток приложений будет постоянно активен, пространство молодого поколения будет постепенно заполняться. Когда JVM не удается разместить объект в области Eden (область Eden заполнена), она будет запущена один раз.STWколлекция стиля молодого поколения. В коллекции молодого поколения уцелевшие объекты из раздела Eden будут скопированы в раздел Survivor; Объекты, выжившие в исходном разделе Survivor, будут повышены доPLAB, раздел нового оставшегося в живых и раздел старого поколения. Оригинальный раздел молодого поколения будет полностью переработан.

В то же время коллекция молодого поколения также отвечает за поддержание возраста (время выживания) объектов и помощь в оценке того, продвигаются ли стареющие (владеющие) объекты в раздел оставшихся в живых или в раздел старого поколения. Коллекция молодого поколения сначала поддерживает общий размер продвигаемых объектов и информацию о возрасте объектов в таблице возраста, а затем заполняет емкость в соответствии с таблицей возраста, размером оставшегося в живых и оставшимся в живых.-XX:TargetSurvivorRatio(по умолчанию 50%), максимальное пороговое значение срока-XX:MaxTenuringThreshold(по умолчанию 15), рассчитайте соответствующий порог срока, любой объект, который превышает порог срока, будет повышен до старости.

смешанная коллекцияCSet of Mixed Collection

После того, как молодое поколение будет постоянно собираться, пространство старого поколения будет постепенно заполняться. Когда пространство, занимаемое старым поколением, превышает порог IHOP для всего отношения кучи.-XX:InitiatingHeapOccupancyPercent(по умолчанию 45%), G1 запустит смешанный цикл сборки мусора.

Чтобы достичь цели паузы, G1 может быть не в состоянии собрать все разделы-кандидаты за один раз, поэтому G1 может генерировать несколько последовательных смешанных коллекций и попеременно выполнять потоки приложения каждый раз.STWПроцесс смешанного сбора похож на процесс сбора молодого поколения.

  • Максимальное общее количество раз, когда JVM проходит циклы смешивания параметров, чтобы определить разделы старого поколения, включенные в набор коллекций молодого поколения CSet.-XX:G1MixedGCCountTarget(по умолчанию 8), процент отходов кучи-XX:G1HeapWastePercent(по умолчанию 5%).

По общему количеству разделов-кандидатов на старость и максимальному общему количеству смешанных циклов определяется, что каждый раз, когда он содержитCSetМинимальное количество разделов;

В соответствии с процентом отходов кучи, когда сбор достигает параметра, новый смешанный сбор не запускается. и каждый раз добавляю кCSetПерегородки расположены в соответствии с расчетной эффективностью ГХ.

Активный цикл G1

Сборка мусора G1 включает в себя следующее:

  • Параллельный цикл маркировки (параллельный сбор) аналогичныйCMSПараллельный процесс сбора.

  • Коллекция Young (YGC, Коллекция Young,STW)

  • Смешанный цикл сбора (Смешанный сбор,STW)

  • Полный ГК (ФСК,STW)До JDK10 FGC подвергался серийной переработке, а JDK10+ может подвергаться параллельной переработке.

параллельный цикл маркировкиConcurrent Marking Cycle

Параллельный цикл маркировки является очень важной фазой в G1, на этой фазе будут определены наиболее мусорные разделы старого поколения для цикла смешанного сбора.

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

При достижении порога IHOP-XX:InitiatingHeapOccupancyPercent(Старое поколение учитывает всю долю кучи, по умолчанию 45%), будет запущен параллельный цикл маркировки.

Весь цикл параллельной маркировки будет состоять из нескольких этапов: начальная маркировка, сканирование корневой области, параллельная маркировка, примечание и очистка.

Среди них первоначальная маркировка (активная со сбором молодого поколения), повторная маркировка и очистка - STW,Если одновременная маркировка не позволяет отметить уцелевшие объекты, G1 может инициировать несколько коллекций молодого поколения в процессе одновременной маркировки (YGC).

Initial Marking(начальный знак, STW)

Он помечает объекты, которые напрямую доступны из корня GC.

Фактически, когда порог IHOP достигнут, G1 не инициирует сразу параллельный цикл маркировки, а ждет следующего сбора молодого поколения и использует период времени STW, собранный молодым поколением, для завершения начальной маркировки.Этот метод называется Совмещение).

Root region scanning(сканирование корневого раздела)

После того, как начальная пауза пометки заканчивается, молодое поколение собирает также завершенную работу по копированию объектов в Survivor, и поток приложения становится активным. В настоящее время, чтобы обеспечить правильность алгоритма маркировки, все объекты, вновь скопированные в раздел Survivor, должны быть просканированы и помечены как корневые.Этот процесс называется сканированием корневого региона, а отсканированный раздел Survivor также называется корневым регионом. .

Concurrent Marking(одновременная маркировка)

Эта фаза начинается с корня GC для маркировки объектов в куче, поток маркировки выполняется параллельно с потоком приложения и собирает каждыйRegionинформация о сохранившихся объектах. Выполняемый одновременно с потоком приложения, параллельный поток маркировки запускается в фазе параллельной маркировки параметром-XX:ConcGCThreads(1/4 от количества потоков GC по умолчанию, т.е. -XX:ParallelGCThreads/4) для управления количеством запусков, Каждый поток сканирует только один раздел за разRegion, тем самым помечая уцелевший граф объектов.

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

Remark(перемаркировка, STW)

Отметьте объекты, которые изменились на этапе параллельной маркировки и будут собраны. Этот этап также выполняется параллельно, через параметр-XX:ParallelGCThreadВы можете установить количество потоков GC, доступных, когда GC приостановлен.

Cleanup(очистка, STW)

На этапе очистки в основном выполняются следующие операции:

  • RSetпрочесывая, эвристический алгоритм будет основан на активности иRSetРазмеры определяют разные уровни для разделов, в то время какRSetМатематика также помогает выявлять бесполезные цитаты. параметр-XX:+PrintAdaptiveSizePolicyВы можете включить печать деталей решения эвристического алгоритма;
  • Организуйте разделы кучи, чтобы определить наборы старых разделов с высокой отдачей при восстановлении (на основе свободного места и целей паузы) для смешанных циклов сбора;
  • Идентифицировать все свободные разделы, т. е. найти разделы без живых объектов. Раздел можно восстановить непосредственно на этапе очистки, не дожидаясь следующего цикла сбора.

Коллекция Young Коллекция Young / Цикл смешанной коллекции Цикл смешанной коллекции

Когда приложение запускается, свободное пространство кучи памяти все еще относительно велико, и сбор данных молодого поколения будет запущен только тогда, когда новое поколение будет заполнено;

По мере роста памяти старого поколения при достижении порога IHOP-XX:InitiatingHeapOccupancyPercent(На старое поколение приходится весь коэффициент кучи, по умолчанию 45%), G1 начинает готовиться к сбору пространства старого поколения.

Сначала пройдите параллельные циклы маркировкиConcurrent Marking Cycle, определите высокодоходные старые разделы, как описано выше.

Но тогда G1 не будет сразу запускать смешанную коллекцию, а пусть некоторое время поработает поток приложения, ожидая запуска коллекции молодого поколения.

В этом STW G1 будет претендовать на смешанный цикл сбора. Затем снова запустите поток приложения.Когда будут собраны следующие несколько молодых поколений, разделы старого поколения будут добавлены в CSet.

То есть запускается смешанный сбор, и эти последовательные смешанные сборы называются циклами смешанных сборов (Mixed Collection Cycle).

Молодая коллекция Молодая коллекция,YGC

В каждом процессе сбора есть как параллельные, так и последовательные действия, но они могут быть многопоточными.

В задачах, выполняемых параллельно, если задача слишком тяжелая, другие потоки будут ждать обработки задачи, и эти места нужно оптимизировать.

Следующие части можно просматривать вместе с логом

  • Параллельные действия

    • Сканирование внешнего корня Сканирование внешнего корня: Это действие сканирует корневые каталоги вне кучи (системные каталоги JVM, структуры данных VM, дескрипторы потоков JNI, аппаратные регистры, глобальные переменные, корни потоков в стеке) и находит объекты, которые не добавлены в CSet приостановленного набора сбора. Если системный каталог (один корень) имеет большое количество загруженных классов, это может закончиться временем ожидания, вызванным тем фактом, что действие все еще не завершено после завершения других параллельных действий.

    • Обновление Memorized Collection Обновление RS: Поток оптимизации параллелизма сканирует грязные разделы карты, чтобы обновить буфер журнала для обновления RSet, но обрабатывает только глобальный список буферов. Кроме того, все оставшиеся буферы, которые зарегистрированы, но еще не обработаны потоком оптимизации, обрабатываются на этом этапе и становятся обработанными буферами. Чтобы ограничить время, затрачиваемое на обновление RSet, вы можете установить Процент занятости приостановки.-XX:G1RSetUpdatingPauseTimePercent(по умолчанию 10%, т.е. -XX:MaxGCPauseMills/10). Стоит отметить, что если задача обновления обновления буфера журнала не сокращена, простое сокращение времени обновления набора RSet приведет к уменьшению обработки буфера во время паузы, а работа по обновлению буфера журнала будет перенесена на параллельный поток оптимизации, тем самым увеличивая конкуренцию за ресурсы потока приложения Java.

    • RSet Scan Scan RS: Перед сбором текущего CSet необходимо просканировать RSet раздела CSet с учетом ссылок за пределами раздела. Если RSet загрублен, время сканирования RSet будет увеличено. Включите диагностический режим-XX:UnlockDiagnosticVMOptionsназад, по параметру-XX:+G1SummarizeRSetStatsМожно определить, способны ли параллельные потоки оптимизации своевременно обрабатывать буфер журнала обновлений, и предоставить дополнительную информацию, чтобы помочь создать окно с итоговым значением укрупнения RSet. параметр-XX:G1SummarizeRSetStatsPeriod=nСтатистический период RSet может быть установлен, то есть, сколько GC было опытно выполнять статистику один раз.

    • Сканирование корня кода Сканирование корня кода: сканирование коллекции корня кода, сканирование справочной информации (сканирование nmethod) собственного метода скомпилированного кода JVM и выполнение сканирования RSet. На самом деле, только когда RSet в разделе CSet имеет сильный корневой код, сканирование nmethod будет выполнено, чтобы найти ссылку на CSet.

    • Передача и повторное использование копии объекта: Через выбранный CSet и полный эталонный набор раздела CSet будет выполняться основная часть времени паузы: перенос уцелевших объектов раздела CSet и восстановление пространства раздела CSet. Благодаря механизму кражи работы поток, который копирует объект, сбалансирован по нагрузке, а скопированный и отсканированный активный объект будет скопирован в каждый буфер выделения потока GC GCLAB. G1 регулирует размер молодого поколения, вычисляя и прогнозируя время, необходимое для копирования раздела.

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

    • Параллельные действия вне GC GC Worker Другое: Эта часть — не активность GC, а активность JVM, которая вызывает время паузы GC (например, компиляция JNI).

  • Серийная деятельность

    • Обновление корня кода Исправление корня кода: обновление корня кода в соответствии с объектом передачи.

    • Code Root Purge Code Root Purge: очищает таблицу корневого набора кода.

    • Очистить глобальную метку карты Очистить CT: во время любого цикла сбора PRT, записанный CSet и RSet, будет сканироваться и помечаться в глобальной таблице карт во время сканирования, чтобы предотвратить повторное сканирование. Флаг сканирования в глобальной таблице карт будет очищен в конце цикла сбора.

    • Выберите следующий набор коллекций Выберите CSet: Эта часть в основном используется для коллекции молодого поколения после параллельного цикла маркировки и смешанной коллекции.Во время этих процессов сбора, из-за добавления разделов-кандидатов старого поколения, часто необходимо определить объем следующей коллекции.Сделать определение, но в чистой коллекции молодого поколения будут собраны все собранные разделы, и выбора нет.

    • Обработка ссылок Ref Proc: в основном для мягкой ссылки, слабой ссылки, виртуальной ссылки, окончательной ссылки, ссылки JNI. Когда Ref Proc занимает слишком много времени, вы можете использовать параметры-XX:ParallelRefProcEnabledАктивирует многопоточную обработку ссылок. G1 надеется, что приложения смогут использовать мягкие ссылки с осторожностью, потому что мягкие ссылки всегда будут занимать место в памяти до тех пор, пока они не будут освобождены полным сборщиком мусора, когда пространство будет исчерпано; даже если полный сборщик мусора не произойдет, занятие памяти мягкими ссылками приведет к увеличению по количеству ГК.

    • Ref Enq Ref Enq: это действие может привести к обновлению набора RSet, и в этом случае соответствующая карта будет помечена журналом как грязная.

    • Красные карты: Красные карты.

    • Восстановление бездействующего гигантского раздела Humongous Reclaim: G1 провел оптимизацию: просмотрев все корневые объекты и RSet раздела молодого поколения, если было определено, что в RSet нет ссылки на гигантский объект, это означает, что G1 обнаружил недостижимый гигантский объект, раздел объекта будет переработан.

    • Бесплатный раздел Free CSet: освободите все пространство раздела CSet и добавьте его в свободный раздел.

    • Другие действия Другое: во время GC могут также выполняться другие небольшие действия, требующие много времени, такие как восстановление дескрипторов JNI и т. д.

Коллекция Young после параллельного цикла маркировки

Когда G1 инициирует параллельный цикл маркировки, он не сразу начинает смешанный сбор. G1 сначала будет ждать следующей коллекции молодого поколения, а затем на этой фазе сбора определит CSet (выбрать CSet) для следующей смешанной коллекции.

Смешанный цикл сбора,Mixed GC

Единая смешанная коллекция ничем не отличается от коллекции молодого поколения.

В соответствии с целью паузы разделы старого поколения не могут быть обработаны в одной приостановленной коллекции, а G1 инициирует несколько последовательных смешанных коллекций, что называется циклом смешанной коллекции.

G1 будет вычислять количество разделов, добавляемых в CSet каждый раз, количество раз смешанной коллекции, а также в последней коллекции молодого поколения и следующей смешанной коллекции, G1 будет определять набор разделов (выбрать CSet), добавляемый в CSet следующим время, И определяется, следует ли закончить цикл смешанного сбора.

Гарантийный механизм при сбое передачиFull GC

передача не удалась(Evacuation Failure) означает, что когда G1 не может подать заявку на новый раздел в пространстве кучи, G1 активирует механизм гарантии и выполнит его один раз.STWФормальный однопоточный (JDK10 поддерживает многопоточность) полный сборщик мусора.

Полный сборщик мусора помечает и сжимает всю кучу и в конечном итоге будет содержать только чистые живые объекты. параметр-XX:G1ReservePercent(по умолчанию 10%) Пространство может быть зарезервировано для решения нештатных ситуаций в режиме продвижения, и оно занимает до 50% всего стека, и бессмысленно, если оно больше.

G1 запускает полный сборщик мусора в следующих сценариях и одновременно записывает в журналto-space exhaustedтак же какEvacuation Failure:

  • Не удалось найти доступный свободный раздел при копировании живых объектов из раздела молодого поколения
  • Не удалось найти свободный свободный раздел при переносе живых объектов из раздела старого поколения
  • выделение больших объектовHumongous Objectне может найти достаточно смежных разделов в старом поколении

Поскольку приложения G1 часто имеют большой размер кучи памяти, стоимость сбора полного GC очень высока, и его следует избегать.

вопрос

  • Когда срабатывает одновременная маркировка?
# 启动并发周期 Concurrent Marking Cycle (以及后续的混合周期 MixedGC)时的堆内存占用百分比. G1用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比例。默认45%
# 当堆存活对象占用堆的45%,就会启动G1 中并发标记周期 Concurrent Marking Cycle
-XX:InitiatingHeapOccupancyPercent
  • Когда происходит смешанный GC? Параллельная маркировка в основном предоставляет услуги маркировки для смешанного GC и не является необходимой частью процесса GC.

    Управляемый некоторыми параметрами, он также определяет, какие старые регионы будут выбраны в CSet (набор коллекций).

# 一次 concurrent marking之后,最多执行Mixed GC的次数(默认8)
-XX:G1MixedGCCountTarget
# 堆废物百分比(默认5%),在每次YGC之后和再次发生Mixed GC之前,会检查垃圾占比是否达到此参数,只有达到了,下次才会发生Mixed GC。
-XX:G1HeapWastePercent
# old generation region中的存活对象的占比,只有在此参数之下,才会被选入CSet。
-XX:G1MixedGCLiveThresholdPercent
# 一次Mixed GC中能被选入CSet的最多old generation region数量。
-XX:G1OldCSetRegionThresholdPercent

Подробный журнал сборщика мусора

Параллельный цикл маркировки
[GC concurrent-root-region-scan-start]
[GC concurrent-root-region-scan-end, 0.0094252 secs]
# 根分区扫描,可能会被 YGC 打断,那么结束就是如:[GC pause (G1 Evacuation Pause) (young)[GC concurrent-root-region-scan-end, 0.0007157 secs]
[GC concurrent-mark-start]
[GC concurrent-mark-end, 0.0203881 secs]
# 并发标记阶段
[GC remark [Finalize Marking, 0.0007822 secs] [GC ref-proc, 0.0005279 secs] [Unloading, 0.0013783 secs], 0.0036513 secs]
#  重新标记,STW
 [Times: user=0.01 sys=0.00, real=0.00 secs] 
[GC cleanup 13985K->13985K(20480K), 0.0034675 secs]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
# 清除
Молодое поколение собирает YGC
[GC pause (G1 Evacuation Pause) (young), 0.0022483 secs]
# young -> 年轻代      Evacuation-> 复制存活对象 
   [Parallel Time: 1.0 ms, GC Workers: 10] # 并发执行的GC线程数,以下阶段是并发执行的
      [GC Worker Start (ms): Min: 109.0, Avg: 109.1, Max: 109.1, Diff: 0.2] 
      [Ext Root Scanning (ms): Min: 0.1, Avg: 0.2, Max: 0.3, Diff: 0.2, Sum: 2.3] # 外部根分区扫描
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] # 更新已记忆集合 Update RSet,检测从年轻代指向老年代的对象
         [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0] 
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]# RSet扫描
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1] # 代码根扫描
      [Object Copy (ms): Min: 0.3, Avg: 0.3, Max: 0.4, Diff: 0.1, Sum: 3.5] # 转移和回收,拷贝存活的对象到survivor/old区域
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] # 完成上述任务后,如果任务队列已空,则工作线程会发起终止要求。
         [Termination Attempts: Min: 1, Avg: 5.8, Max: 9, Diff: 8, Sum: 58]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1] # GC外部的并行活动,该部分并非GC的活动,而是JVM的活动导致占用了GC暂停时间(例如JNI编译)。
      [GC Worker Total (ms): Min: 0.5, Avg: 0.6, Max: 0.7, Diff: 0.2, Sum: 5.9]
      [GC Worker End (ms): Min: 109.7, Avg: 109.7, Max: 109.7, Diff: 0.0]
   [Code Root Fixup: 0.0 ms] # 串行任务,根据转移对象更新代码根
   [Code Root Purge: 0.0 ms] #串行任务, 代码根清理
   [Clear CT: 0.5 ms] #串行任务,清除全局卡片 Card Table 标记
   [Other: 0.8 ms]
      [Choose CSet: 0.0 ms] # 选择下次收集集合  CSet
      [Ref Proc: 0.4 ms] # 引用处理 Ref Proc,处理软引用、弱引用、虚引用、final引用、JNI引用
      [Ref Enq: 0.0 ms] # 引用排队 Ref Enq
      [Redirty Cards: 0.3 ms] # 卡片重新脏化 Redirty Cards:重新脏化卡片
      [Humongous Register: 0.0 ms] 
      [Humongous Reclaim: 0.0 ms] # 回收空闲巨型分区 Humongous Reclaim,通过查看所有根对象以及年轻代分区的RSet,如果确定RSet中巨型对象没有任何引用,该对象分区会被回收。
      [Free CSet: 0.0 ms]  # 释放分区 Free CSet
   [Eden: 12288.0K(12288.0K)->0.0B(11264.0K) Survivors: 0.0B->1024.0K Heap: 12288.0K(20480.0K)->832.0K(20480.0K)]
 [Times: user=0.01 sys=0.00, real=0.00 secs] 
# 从年轻代分区拷贝存活对象时,无法找到可用的空闲分区
# 从老年代分区转移存活对象时,无法找到可用的空闲分区 这两种情况之一导致的 YGC
[GC pause (G1 Evacuation Pause) (young) (to-space exhausted), 0.0916534 secs]
# 并发标记周期 Concurrent Marking Cycle 中的 根分区扫描阶段,被 YGC中断
[GC pause (G1 Evacuation Pause) (young)[GC concurrent-root-region-scan-end, 0.0007157 secs]
Смешанный цикл сбора, смешанный GC
# 并发标记周期 Concurrent Marking Cycle 的开始
[GC pause (G1 Evacuation Pause) (young) (initial-mark) , 0.0443460 secs]
Full GC
[Full GC (Allocation Failure) 20480K->9656K(20480K), 0.0189481 secs]
   [Eden: 0.0B(1024.0K)->0.0B(5120.0K) Survivors: 0.0B->0.0B Heap: 20480.0K(20480.0K)->9656.8K(20480.0K)], [Metaspace: 4960K->4954K(1056768K)]
 [Times: user=0.03 sys=0.00, real=0.02 secs] 

использованная литература

by Sven Augustus my.oschina.net/langxSpirit

Эта статья публикуется блогерами и другими операционными платформами.OpenWriteвыпускать