Систематизация сборщиков мусора в HotSpot, IBM J9, JRockit JVMs

в 18:33, , рубрики: hotspot, java, Программирование, метки: ,

Введение

Данная статья призвана систематезировать знания о всех современных сборщиках мусора, используемых в HotSpot, JRockit и J9 JVMs. Статья содержит краткий обзор всех режимов сборки мусора с проведенными аналогиями между всеми рассматриваемыми здесь JVM. Статья будет интересна всем, кто интересуется вопросом GC, а также будет полезна тем, кто рассматривает или планирует совершать портирование JAVA приложений на альтернативные JVM.

Предполагается, что читатель уже знаком с базовыми понятиями сборки мусора — такими, как Копирующий сборщик (Copying collector), алгоритм Mark-Sweep-Compact, сборка мусора по поколениям (Generational collection).

Также сразу следует сказать, что статья не претендует на полноту изложения алгоритмов сборки мусора, в сети достаточно хорошо иллюстрированных материалов по любым из алгоритмов. Реализации похожих по концепции алгоритмов могут сильно отличаться от одной JVM к другой — если однопоточный Mark-Sweep-Compact везде реализован примерно одинаково, то конкурентый Mark-Sweep-Compact уже имеет различные вариации, которые здесь также не затрагиваются.

Oracle HostSpot JVM (версии 6 и 7)

Практически все режимы сборки мусора в HotSpot используют сборку по поколениям. Вся Heap разбивается на 3 поколения в зависимости от возраста объектов — соответственно Young для молодых, Tenured для «зрелых» и Perm для классов и констант-пулов. В свою очередь Young поколение разделяется еще на 3 области — Eden и 2 Surviver области. Вначале объекты создаются в Eden, затем попадают в Surviver области (один или более раз), а затем уже только в Tenured. Для G1 разбиение по поколениям тоже существует, но имеет другой характер (описано ниже).

Copy (-XX:+UseSerialGC)
Однопоточный (serial) копирующий коллектор для Young поколения.

ParNew (-XX:+UseParNewGC)
Многопоточный (parallel) копирующий коллектор для Young поколения.

MarkSweepCompact (-XX:+UseSerialGC)
Однопоточный коллектор для Tenured поколения использующий Mark-Sweep-Compact алгоритм.

ConcurrentMarkSweep (-XX:+UseConcMarkSweepGC)
Конкурентный Mark-Sweep (concurrent) коллектор для Tenured поколения, большую часть времени работающий одновременно с потоками приложения. При сильной фрагментации обращается за помощью к однопоточному MarkSweepCompact. Возможны дополнительные параметры:

  • -XX:±CMSIncrementalMode — uses or disables an incremental concurrent GC algorithm
  • -XX:±CMSConcurrentMTEnabled — uses or disables parallel (multiple threads) concurrent GC algorithm
  • -XX:±UseCMSCompactAtFullCollection — uses or disables a compaction when a full GC occurs

PS Scavenge + PS MarkSweep (-XX:+UseParallelGC -XX:+UseParallelOldGC)
Для Young поколения используется многопоточный копирующий коллектор PS Scavenge аналогичный ParNew. Для Tenured поколения используется PS MarkSweep — многопоточная версия Mark-Sweep-Compact алгоритма. Данная пара коллекторов поддерживает т. н. Adaptive Size Policy (или GC ergonomics) — возможность JVM автоматически оптимизировать размеры Young и Tenured поколений для достижения заданных пауз. Возможны дополнительные параметры:

  • -XX:±UseAdaptiveSizePolicy — uses or disables Adaptive Size Policy
  • -XX:MaxGCPauseMillis=nnn — sets desirable max GC pause time
  • -XX:GCTimeRatio=nnn — sets desirable relation between application and GC work times

G1 Young Generation + G1 Mixed Generation (-XX:+UseG1GC)
Новый режим использующий «региональную» сборку. Heap разделяется на множество регионов равного размера (0.5-2 мб). Конкурентный трасирующе-маркирущий процесс оценивает размер живых объектов в регионах, это происходит параллельно без остановки потоков приложения. При следующем цикле GC обрабатывает все Young регионы (специальные регионы, в которых создаются новые объекты), а также несколько тех, в которых наименьший размер живых объектов. Т.о. сборщик минимизирует количество копирований между регионами. Здесь также доступна возможность задавать желаемое время пауз:

  • -XX:MaxGCPauseMillis=nnn — sets desirable max GC pause time

IBM J9 JVM

В отличии от HotSpot, в J9 только один режим использует сборку по поколениям. Однако в данном случае, Young поколение разбивается не на 3, а на 2 области — Eden и Surviver. Т.о. объект из Surviver сразу попадет в Tenured. А если Eden < Surviver, то некоторые объекты сразу имеют шанс попасть из Eden в Tenured.

-Xgcpolicy:optthruput
Многопоточный Mark-Sweep-Compact коллектор, обрабатывающий весь Heap.

-Xgcpolicy:optavgpause
Конкурентный Mark-Sweep-Compact коллектор для всего Heap, большую часть времени работающий одновременно с приложением. Призван сгладить паузы вызываемые GC.

-Xgcpolicy:gencon
Коллектор по поколениям. Для Young поколения используется многопоточный копирующий коллектор, однако вместо 3х областей используется только 2 — Eden и Surviver. Объекты попавшие в Surviver при следующем цикле GC попадут в Tenured поколение. Для Tenured поколения используется вышеописаный конкурентный Mark-Sweep-Compact коллектор.

-Xgcpolicy:balanced
Новый коллектор использующий разделение Heap на множество регионов. Аналогичен по концепции G1 в Oracle HotSpot.

Oracle JRockit JVM

В JRockit 2 режима сборки по поколениям, однако Young поколение еще проще — оно вообще не разбивается, и при первом же цикле сборщика, объекты из Eden сразу попадают в Tenured.
JRockit позволяет выбирать между динамическими и статическими режимами. Динамические режимы — throughput, pausetime, deterministic — определяют цель, и динамически могут изменять параметры а также сам алгоритм сборки в зависимиости от ситуации. Также существуют статические режимы, которые более точно определяют способ сборки мусора, на них мы и остановимся:

-Xgc:singlepar
Многопоточный Mark-Sweep-Compact коллектор, обрабатывающий весь Heap.

-Xgc:genpar
Коллектор по поколениям. Для Young поколения используется многопоточный копирующий коллектор. Для Tenured поколения используется многопоточный Mark-Sweep-Compact.

-Xgc:singlecon
Конкурентный Mark-Sweep-Compact коллектор для всего Heap, большую часть времени работающий одновременно с приложением.

-Xgc:gencon
Коллектор по поколениям. Для Young поколения используется однопоточный копирующий коллектор. Для Tenured поколения используется конкурентный Mark-Sweep-Compact коллектор, аналогичный singlecon.

Таблица аналогий

Oracle HotSpot IBM J9 Oracle JRockit
-XX:+UseSerialGC

Copy + MarkSweepCompact

-XX:+UseG1GC

G1 Young + G1 Mixed

-Xgcpolicy:balanced
-XX:+UseParallelGC
-XX:+UseParallelOldGC

PS Scavenge + PS MarkSweep

-Xgcpolicy:optthruput* -Xgc:genpar
-Xgc:singlepar*
-XX:+UseParNewGC

ParNew + MarkSweepCompact

-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC

ParNew + ConcurrentMarkSweep

-Xgcpolicy:optavgpause* -Xgc:singlecon*
-XX:+UseConcMarkSweepGC
-XX:-UseParNewGC

Copy + ConcurrentMarkSweep

-Xgcpolicy:gencon
-Xgcpolicy:optavgpause*
-Xgc:gencon
-Xgc:singlecon*

* — сходство только по способу чистки Tenured поколения.

Источники

http://www.fasterj.com/articles/oraclecollectors1.shtml

http://www.ibm.com/developerworks/websphere/techjournal/1106_bailey/1106_bailey.html

http://www.ibm.com/developerworks/websphere/techjournal/1108_sciampacone/1108_sciampacone.html

http://www.techpaste.com/2012/02/java-garbage-collectors-gc/

http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/memman.html#wp1087125

http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp1017849

Автор: vinodel

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js