Примечание. Следующий контент в основном сочетается с 3-м резюме «Углубленное понимание JVM».
Продолжая предыдущую, поговорим оG1
,G1
в качестве основногоJVM GC
, используется в качестве сборщика мусора, в основном используемого основным Интернетом, понимаетеG1
Принцип переработки и процесс переработки могут помочь нам лучше определить проблему и решить ее.
-XX:+UseG1GC
включиG1 GC
Раздел памяти G1
G1
выглядит иCMS
Похоже, но реализация сильно отличается.
традиционное поколениеGC
Разделите общую память на несколько больших областей, таких какEden,S0,S1,Tenured
Ждать.
а такжеG1
Разделить область памяти на Nпрерывистый,тот же размеризRegion
,Region
Конкретный размер составляет от 1 до 32 МБ, в зависимости от общего объема памяти, а цель — не более 2048. Как показано ниже:
каждыйRegion
существуетG1
играл разные роли, напримерEden
(новый район), напримерSurvivor
(зона выживания), илиOld
(старость)
В дополнение к традиционной старости новое поколение,G1
также разделенHumongous
площадь, используемая для хранения огромных предметов (humongous object,H-obj
).
Для огромных объектов стоит отметить следующие моменты:
-
H-obj
определяется как большее или равноеRegion
половина объекта -
H-obj
назначить непосредственно наOld gen
, чтобы предотвратить частое копирование. ноH-obj
переработка неMixed GC
этап, ноconcurrent marking
на сценеclean up
процесс иfull GC
Обратите внимание на этот момент, в процессе настройки вы
GC
Это предложение часто встречается в журнале[GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0029216 secs]
Вопрос в том, почему
Humongous Allocation
но вызвалyong gc
.Причина в том, чтобы пройти
yong gc
изinitial-mark
Началоconcurrent marking
, а затем черезclean up
Перерабатывайте большие предметыЕсли вы хотите увидеть
G1
При регистрации, чтобы облегчить и быстро добратьсяGC
эффект, вы можете выделить несколько больших объектов напрямую, чтобы заполнить всю кучу и вызватьGC
, но если свет представляет собой большой объект, вы можете найтиGC
журнал неMixed GC
, но частоYong GC
а такжеConcurrent Marking
, вот почему -
H-obj
никогда не будет перемещен, хотяG1
Алгоритм повторного использования обычно основан на сопоставлении меток, но дляH-obj
Он никогда не будет перемещен и либо будет переработан напрямую, либо будет существовать всегда. следовательноH-obj
Может вызывать большую фрагментацию памяти и вызывать частыеGC
G1
процесс переработки
G1
Форма разбиения памяти определяетG1
Необходимо управлять как молодым, так и старым поколением. В зависимости от области утилизации,G1
Существует два режима рециркуляции:
- Восстанавливается лишь часть памяти молодого поколения:
Yong GC
- Восстановите всю память молодого поколения и немного памяти старого поколения:
Mixed GC
когда
mixed gc
Скорость рециркуляции не поспевает за скоростью выделения памяти,G1
будет использовать один поток (используяSerial Old
код) дляFull GC
Среди них весьYong GC
процесс назадSTW
,а такжеMixed GC
В основном он включает в себя два этапа: первый этап - параллельный цикл маркировки (Concurrent Marking
), этот процесс в основном для маркировки, а после завершения параллельной маркировки выполняется сборка мусора старого поколения (Evacuation
): Этот процесс в основном копирует и перемещает объекты, организуетRegion
.
Mixed GC
По логике надо сказать сначалаYong Gc
,НоYong GC
кажется нетG1
фокус на рециркуляции, и нет параметров для контроляYong GC
, так что пока пропустите это здесь. Но вы должны знать, чтоYong GC
Процесс утилизации аналогичен другим сборщикам мусора, и он также сначала помечается, а затем копируется. Но весь процесс будетSTW
, и из-заYong GC
Процесс маркировки и оборотная сторонаMixed GC
Маркеры параллелизма в (Concurrent Marking
) на первом этапе начальная отметка (initial marking
) выполняет ту же работу, поэтомуConcurrent Marking
Начальная фаза маркировки всегда несетYong GC
провести.
Mixed GC
Разделенный на два этапа, первый этап представляет собой одновременную маркировку, а второй этап — скрининг и переработку. Параллельный процесс маркировки выглядит следующим образом:
- начальная маркировка
- одновременная маркировка
- итоговая маркировка (окончательная маркировка, перемаркировка)
- уборка
Очистка здесь заключается не в очистке объекта (не то же самое, что в CMS).Хотя «Понимание JVM» будет очищать, фильтровать и перерабатывать в процесс, но
GC
В журнале это совершенно отдельные процессы. здесь сGC
Журнал имеет преимущественную силу
После завершения маркировкиG1
Затем выберите некоторые области для проверки и переработки. Обратите внимание, что эти этапы могут выполняться отдельно, то есть методы выполнения могут быть следующими:
启动程序
-> young GC
-> young GC
-> young GC
-> young GC + initial marking
(... concurrent marking ...)
-> young GC (... concurrent marking ...)
(... concurrent marking ...)
-> young GC (... concurrent marking ...)
-> final marking
-> cleanup
-> mixed GC
-> mixed GC
-> mixed GC
...
-> mixed GC
-> young GC + initial marking
(... concurrent marking ...)
Далее мы подробно объясним, что делает каждый этап маркировки.
начальная маркировка:МогуStop The World
, от маркировки всехGC Root
Объекты, до которых можно добраться непосредственно выездом. Хотя процесс и будет приостановлен, он заимствованYong GC
, поэтому нет дополнительной отдельной фазы приостановки.
одновременная маркировка: Параллельная стадия. Начиная с объектов, проверенных на предыдущем этапе, он обходит и ищет один за другим, и каждый объект помечается как живой. Примечание. Этот процесс также сканируетSATB
(Параллельный снимок) Записанная ссылка.
Вызов моментального снимка параллелизма: это решение проблемы, связанной с тем, что объекты могут быть неправильно помечены из-за того, что пользователи изменяют ссылочное отношение во время параллельного процесса.
CMS
Здесь используется инкрементное обновлениеG1
Используется одновременный снимок, который записывает все отношения ссылок в начале параллельной метки.
окончательная маркировка (перемаркировка): МогуSTW
, хотя предыдущий параллельный процесс маркировки сканируетSATB
, но ведь предыдущий этап — это все-таки параллельный процесс, поэтому после завершения параллельной маркировки все пользовательские потоки нужно снова приостановить и снова разметитьSATB
. Этот процесс также обрабатывает слабые ссылки.
Все три этапа являются
CMS
довольно похожи,CMS
Слабые ссылки также обрабатываются на заключительном этапе маркировки.но
CMS
Завершающий этап маркировки требует повторного сканирования всейYong gen
, так что можноCMS
изremark
Этапы будут очень медленными.
очистить: Фаза паузы. Очистите и сбросьте состояние маркера. считать каждыйregion
Количество объектов, помеченных как уцелевшие на данном этапе. Если на данном этапе будет найден регион, в котором нет живых объектов, он целиком будет возвращен в список выделяемых регионов.
После завершения маркировки выполняется очистка (Evacuation
), этот этап полностью приостановлен. он отвечает за размещение частиregion
Скопируйте живой объект в пустойregion
внутри, а затем утилизируйте оригиналregion
пробел, вы можете выбрать столько, сколько хотите на этом этапеregion
сформировать набор коллекций (Collection Set
), выбрав набор коллекций, вы можетеCollection Set
Объекты копируются параллельно в новыйregion
середина.
ПонялG1
Общий процесс переработки, следующее сравнениеCMS
мы можем видетьG1
Как решить некоторые проблемы в параллельном процессе:
-
Помните набор: как упоминалось ранее, для ссылок между поколениями
CMS
Выбрано не поддерживать набор памяти нового поколения для старого поколения, потому что новое поколение меняется слишком быстро, а стоимость обслуживания относительно велика, иG1
Решение, независимо отYong GC
все ещеMixed GC
, будетYong Gen
ПрисоединяйсяCollection Set
Короче говоря, либо только новое поколение перерабатывается, либо все новое поколение и старое поколение перерабатываются вместе, что позволяет избежать сохранения памяти старого поколения, установленной новым поколением.Здесь обсуждается только обслуживание набора памяти для ссылки старого поколения на старое поколение.Ссылка старого поколения на новое поколение по-прежнему будет поддерживать набор памяти.
-
Справочные изменения во время параллелизма: здесь
Remarking
этапе мы уже сказали,CMS
использовать схему инкрементного обновления, аG1
используется параллельный снимок (STAB snapshot-at-the-beginning
) -
Что касается обслуживания наборов памяти и одновременных моментальных снимков,
G1
Тоже через барьер записи(write barrier
) для поддержания.
Журнал утилизации G1
talk is cheap, show me the code
Вышеупомянутый процесс в основном суммируется с помощью "Глубокого понимания JVM" и некоторой информации в Интернете. Так ли это? Им еще нужно управлять. Давайте посмотрим.G1
Журнал утилизации:
Yong GC
//GC 原因:分配大对象 GC类型yong gc 此次带有并发标记的initial mark 此次GC花费0.0130262s
[GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0130262 secs]
//暂停过程中,并行收集花费4.5ms 使用4个线程同时收集
[Parallel Time: 4.5 ms, GC Workers: 4]
//并发工作开始时间戳
[GC Worker Start (ms): Min: 1046.3, Avg: 1046.3, Max: 1046.4, Diff: 0.1]
//扫描root集合(线程栈、JNI、全局变量、系统表等等)花费的时间
[Ext Root Scanning (ms): Min: 0.9, Avg: 1.0, Max: 1.2, Diff: 0.3, Sum: 4.0]
//更新Remember Set的时间
//由于Remember Set的维护是通过写屏障结合缓冲区实现的,这里Update RS就是
//处理完缓冲区里的元素的时间,用来保证当前Remember Set是最新
[Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
//Update RS 过程中处理了多少缓冲区
[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]
//扫描代码中的Root(局部变量)节点时间
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.1]
//拷贝(疏散)对象的时间
[Object Copy (ms): Min: 3.0, Avg: 3.0, Max: 3.1, Diff: 0.0, Sum: 12.1]
//线程窃取算法,每个线程完成任务后会尝试帮其他线程完成剩余的任务
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
//线程成功窃取任务的次数
[Termination Attempts: Min: 1, Avg: 1.3, Max: 2, Diff: 1, Sum: 5]
//GC 过程中完成其他任务的时间
[GC Worker Other (ms): Min: 0.1, Avg: 0.2, Max: 0.3, Diff: 0.2, Sum: 0.8]
//展示每个垃圾收集线程的最小、最大、平均、差值和总共时间。
[GC Worker Total (ms): Min: 4.2, Avg: 4.3, Max: 4.3, Diff: 0.1, Sum: 17.1]
//min表示最早的完成任务的线程的时间,max表示最晚接受任务的线程时间
[GC Worker End (ms): Min: 1050.6, Avg: 1050.6, Max: 1050.6, Diff: 0.0]
//释放管理并行垃圾收集活动数据结构
[Code Root Fixup: 0.0 ms]
//清理其他数据结构
[Code Root Purge: 0.0 ms]
//清理card table (Remember Set)
[Clear CT: 0.8 ms]
//其他功能
[Other: 7.8 ms]
//评估需要收集的区域。YongGC 并不是全部收集,而是根据期望收集
[Choose CSet: 0.0 ms]
//处理Java中各种引用soft、weak、final、phantom、JNI等等。
[Ref Proc: 5.2 ms]
//遍历所有的引用,将不能回收的放入pending列表
[Ref Enq: 0.1 ms]
//在回收过程中被修改的card将会被重置为dirty
[Redirty Cards: 0.4 ms]
[Humongous Register: 0.0 ms]
[Humongous Reclaim: 0.0 ms]
//将要释放的分区还回到free列表。
[Free CSet: 0.1 ms]
//Eden 回收前使用3072K 总共12M ——> 回收后使用0B,总共11M
//Survivors 回收前使用0B,回收后使用1024K
//整个堆回收前使用101M 总共256M,回收后使用99M,总共256M
//可以看到这里新生代没有占满就开始Yong GC,其目的是为了开启Concurrent Marking
[Eden: 3072.0K(12.0M)->0.0B(11.0M) Survivors: 0.0B->1024.0K Heap: 101.0M(256.0M)->99.0M(256.0M)]
[Times: user=0.00 sys=0.00, real=0.01 secs]
Concurrent Marking
Параллельная маркировка обычно происходит вYong GC
Позже.Yong GC
после этогоinitial mark
охватывать
//扫描GC Roots
[GC concurrent-root-region-scan-start]
//扫描GC Roots完成,花费0.0004341s
[GC concurrent-root-region-scan-end, 0.0004341 secs]
//并发标记阶段开始
[GC concurrent-mark-start]
//并发标记介绍。花费0.0002240s
[GC concurrent-mark-end, 0.0002240 secs]
//重新标记开始,会STW.
//Finalize Marking花费0.0006341s
//处理引用:主要是若引用。花费0.0000478 secs
//卸载类。花费0.0008091 secs
//总共花费0.0020776 secs
[GC remark [Finalize Marking, 0.0006341 secs] [GC ref-proc, 0.0000478 secs] [Unloading, 0.0008091 secs], 0.0020776 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
//清理阶段 会STW
//主要: 标记所有`initial mark`阶段之后分配的对象,标记至少有一个存活对象的Region
//清理没有存活对象的Old Region和Humongous Region
//处理没有任何存活对象的RSet
//对所有Old Region 按照对象的存活率进行排序
//清理Humongous Region前使用了150M,清理后使用了150M ,耗时0.0013110s
[GC cleanup 150M->150M(256M), 0.0013110 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
Mixed GC
Когда одновременная маркировка завершена, вы можете продолжитьMixed GC
сейчас,Mixed GC
Основная работа заключается в переработке выбранных в процессе параллельной маркировки.Region
Mixed GC
проделанная работа иYong GC
Процесс в основном такой же, за исключением того, что переработанный контент основан на параллельной марке.
G1
Возможно, не удастся собрать все разделы-кандидаты за один раз, поэтомуG1
Может создавать несколько последовательных смешанных коллекций и альтернативное выполнение потоков приложений.
[GC pause (G1 Evacuation Pause) (mixed), 0.0080519 secs]
[Parallel Time: 7.6 ms, GC Workers: 4]
[GC Worker Start (ms): Min: 140411.4, Avg: 140415.1, Max: 140418.9, Diff: 7.4]
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.2, Max: 0.5, Diff: 0.4, Sum: 1.0]
[Update RS (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.3]
[Processed Buffers: Min: 0, Avg: 1.3, Max: 4, Diff: 4, Sum: 5]
[Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Object Copy (ms): Min: 0.0, Avg: 2.6, Max: 5.2, Diff: 5.2, Sum: 10.3]
[Termination (ms): Min: 0.0, Avg: 0.9, Max: 1.8, Diff: 1.8, Sum: 3.4]
[Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 4]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
[GC Worker Total (ms): Min: 0.1, Avg: 3.8, Max: 7.5, Diff: 7.4, Sum: 15.2]
[GC Worker End (ms): Min: 140418.9, Avg: 140418.9, Max: 140418.9, Diff: 0.0]
[Code Root Fixup: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.1 ms]
[Other: 0.4 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.1 ms]
[Humongous Register: 0.0 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.0 ms]
[Eden: 4096.0K(4096.0K)->0.0B(138.0M) Survivors: 8192.0K->2048.0K Heap: 68.0M(256.0M)->65.5M(256.0M)]
[Times: user=0.03 sys=0.00, real=0.01 secs]
Журналы публикуются здесь только для того, чтобы показать, что их содержание одинаково, поэтому я не буду продолжать здесь комментировать.
Full GC
G1 Full GC
//GC类型:Full GC GC原因:调用System.gc() GC前内存使用298M GC后使用509K 花费时间:0.0101774s
[Full GC (System.gc()) 298M->509K(512M), 0.0101774 secs]
//新生代:GC前使用122M GC后使用0B 总容量由154M扩容为230M
//幸存区:GC前使用4096K GC后使用0B
//总内存:GC前使用298M GC后使用509K 总量量512M不变
//元空间:GC前使用3308K GC后使用3308K 总容量1056768K
[Eden: 122.0M(154.0M)->0.0B(230.0M) Survivors: 4096.0K->0.0B Heap: 298.8M(512.0M)->509.4K(512.0M)], [Metaspace: 3308K->3308K(1056768K)]
[Times: user=0.01 sys=0.00, real=0.01 secs]
можно посмотреть на этот разGC
Используемое время составляет 10 мс, но это только тогда, когда вся куча составляет всего 512 МБ, а используется только 300 МБ,G1
да нетFull GC
механизм,G1 GC
используетсяSerial Old
(позже оптимизирован для многопоточности, но все еще относительно медленный), поэтомуFull GC
Он будет приостановлен на долгое время, поэтому в производственной среде обязательно обратите вниманиеFull GC
, обычно раз в несколько днейFull GC
Это приемлемо.
G1 Full GC
Причины, как правило, следующие:
-
Mixed GC
Не могу угнаться за скоростью выделения памяти, толькоFull GC
Чтобы освободить память, решение в этом случае будет рассмотрено позже -
MetaSpace
Недостаточно, для большого количества классов, использующих отражение и динамические прокси, каждый класс динамических прокси будет генерировать новый класс, и в то же времяclass
Информация хранится в метапространстве, поэтому, если метапространства недостаточно,G1
будет полагаться наFull GC
Чтобы расширить метапространство, решение в этом случае состоит в том, чтобы увеличить начальный размер метапространства. -
Humongous
Выделение не удалось, как упоминалось ранееG1
При выделении крупных объектов утилизация производится путемConcurrent Marking
илиFull GC
, поэтому, если выделение большого объекта не удается, это может вызватьFull GC
Конкретные правила здесь не очень ясны, потому что при тестировании
Humongous
вызваныConcurrent Marking
.
Настройка G1
Я так много сказал раньше, просто чтобы понять, когдаGC
Как настроить, когда это влияет на онлайн-среду. Поэтому поймитеG1
В процессе переработки вы обычно можете понять роль каждого параметра и способы его изменения.
-
-XX:+UseG1GC
: использоватьG1
переработчик. -
-XX:MaxGCPauseMillis = 200
: Установите максимальную цель паузы. По умолчанию 200,G1
Он приложит все усилия для достижения этой цели. Это целевое значение необходимо скорректировать в соответствии с проектом. Если время слишком мало, это может привести к падению пропускной способности.Mixed GC
Перерабатывается слишком мало мусора, что приводит к окончательному накоплению мусораFull GC
, если время слишком велико, это может ухудшить работу пользователя. -
-XX:InitiatingHeapOccupancyPercent = 45
: указывает на начало параллелизмаGC
Порог использования кучи для цикла, когда использование всей кучи достигает порога, запускается параллельный цикл. этот параметр иCMS
То же самое в основном используется для предотвращенияMixed GC
Параллелизм в процессе не выполняется.Если параллельный сбор выполняется слишком поздно, оставшейся памяти в параллельном процессе может не хватить для удовлетворения памяти древовидного демона, что приведет кG1
Отказаться от одновременной маркировки, перейти наFull GC
, Эта ситуация вообще может бытьGC
видеть вto-space exhausted
шрифт.Этот параметр нельзя отрегулировать слишком маленьким, слишком маленький приведет к непрерывному циклу, занимающему
CPU
ресурс. -
-XX:G1MixedGCCountTarget=8
: каждый разMixed GC
Объем старой памяти, подлежащей переработке, по умолчанию равен 8, это тоже для решения проблемыto-space exhausted
проблема каждый разMixed GC
Recycle больше, у старого поколения будет больше свободной памяти, но соответствующее время паузы может увеличиться. -
-XX:ConcGCThreads
: каждый разGC
в использованииCPU
Количество, стоимость не фиксирована. Также для решенияto-space exhausted
Проблема использования большего количества потоков, тогдаGC
будет быстрее, за счет пользователяCPU
Время будет занято. -
-XX:G1ReservePercent=10%
: Количество подвесных потолков, функция резервирования10%
Пространство не используется и зарезервировано для параллельных циклов, которые могут возникнуть, когдаto-space exhausted
использовать, когда есть проблема, чтобы предотвратить возникновениеto-space exhausted
, слишком большое резервирование может привести к трате памяти -
Не устанавливать размер молодого поколения: не использовать
-Xmn
,так какG1
заключается в необходимости увеличить или уменьшить размер молодого поколения, что, если установить, приведет кG1
Цели времени паузы не могут быть использованы.
выше, простоG1
Общие параметры, которые требуют внимания, конечно, могут быть и другие проблемы, такие как выделение больших объектов, размер метапространства и т. д. В общем, поймитеGC
Процесс утилизации, много практики, в общем можно пройтиGC
войти, чтобы найти проблему.
использованная литература:
Некоторые ключевые технологии Java Hotspot G1 GC -- Техническая команда Meituan
Глубокое понимание журнала сборщика мусора G1 (1)
Garbage First Garbage Collector Tuning
Руководство по оптимизации сборки мусора виртуальной машины HotSpot — G1
— сказал Жирный Мао, резюмируя заметки о чтении классических книг по Java.