Java Основные и мелкие коллекции мусора

Я читал об Garbage Collection в Java и SO Q & A, но я смущен о типах Мусорной коллекции.

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

Теперь мои вопросы:

  1. Что означает полный GC: а) Означает ли это, что выполняются как Малая, так и Большая коллекции? Или b) Полный GC == Основные коллекции? Который из них?
  2. Если a), означает ли это, что Малая коллекция все еще выполняется с использованием нескольких потоков, тогда как майор был выполнен с использованием Single?
  3. Если b), означает ли это, что "Молодые и старые поколения" были очищены с помощью Single Thread?

Кроме того, 4. Полноценный GC влияет только на OldGeneration или YoungGeneration?

Заранее спасибо.

Ответ 1

Позволь мне объяснить.

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

Здесь что-то понять. По умолчанию в большинстве новых систем JVM использует два разных сборщика мусора для молодых и старых поколений. На моей моей машине: у меня есть Parallel New Collector для молодого поколения и параллельного Mark и Sweep Collector для более старого поколения.

Незначительная коллекция запускается, когда JVM не может выделить место для нового объекта (помните: новые объекты всегда выделяются в области Young Generation Eden).

Следующий вопрос:

Что означает полный GC: а) Означает ли это, что выполняются как Малая, так и Большая коллекции? Или b) Полный GC == Основные коллекции? Который из них?

а также,

Кроме того, 4. Полноценный GC влияет только на OldGeneration или YoungGeneration?

Это зависит. JVM сообщает каждую основную коллекцию как полную GC. [Попробуйте с этими флагами java -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamp ]. Педантичное определение состоит в том, что Full GC запускает Minor сначала, а затем Major (хотя порядок можно переключить, если "Пожилое поколение" заполнено, и в этом случае он сначала освобождается, чтобы позволить ему получать объекты из Young Generation).

Хорошо, вернемся к точке. JVM рассматривает Major Collection [в Старом (или Пермском) поколении] как Full GC. Ниже приведены результаты из программы, которую я смог быстро написать, чтобы проиллюстрировать эту точку. Первая строка - Minor GC, вторая - Major (Full) GC. Вы можете видеть, что это произошло только в "Старом поколении" (CMS) и удалось сократить старое поколение от 1082K до 1034K.

  • 11.431: [GC 11.431: [ParNew: 1152K->128K(1152K), 0.0009893 secs] 2111K->1210K(6464K), 0.0010182 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
  • 17.882: [Full GC (System) 17.882: [CMS: 1082K->1034K(5312K), 0.0212614 secs] 2034K->1034K(6464K), [CMS Perm: 9426K->9410K(21248K)], 0.0213200 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

Следующий вопрос:

Если a), означает ли это, что Малая коллекция все еще выполняется с использованием нескольких потоков, тогда как майор был выполнен с использованием Single?

Да. См. Начало моего ответа. Молодые и пожилые поколения обслуживаются разными Коллекционерами. Для молодого поколения вы можете использовать любое из следующих действий:

  • -XX:+UseSerialGC
  • -XX:+UseParallelGC
  • -XX:+UseParNewGC

Для старого поколения доступны следующие варианты:

  • -XX:+UseParallelOldGC
  • -XX:+UseConcMarkSweepGC

Ответ 2

Хотя ответ гоблина по-прежнему правилен в широких мазках, по крайней мере эта часть теперь устарела:

Это зависит. JVM сообщает каждую основную коллекцию как полную GC.

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