JVM Колектори за боклук

1. Общ преглед

В този бърз урок ще покажем основите на различните изпълнения на JVM Garbage Collection (GC) . Освен това ще разберем как да активираме определен тип Събиране на боклук в нашите приложения.

2. Кратко въведение в събирането на боклука

От името изглежда, че Garbage Collection се занимава с намирането и изтриването на боклука от паметта. Всъщност обаче Garbage Collection проследява всеки обект, наличен в JVM пространството за купчина, и премахва неизползваните.

С прости думи, GC работи в две прости стъпки, известни като Mark и Sweep:

  • Марк - там събирачът на боклук идентифицира кои части памет се използват и кои не
  • Размах - тази стъпка премахва обекти, идентифицирани по време на фазата „маркиране“

Предимства:

  • Няма ръчно разпределение на паметта / обработка на освобождаване, тъй като неизползваното място в паметта се обработва автоматично от GC
  • Без режийни разходи за работа с Dangling Pointer
  • Автоматично управление на изтичане на памет ( GC сам по себе си не може да гарантира пълното доказателство за изтичане на памет, но се грижи за голяма част от него)

Недостатъци:

  • Тъй като JVM трябва да следи създаването / изтриването на референтни обекти, тази дейност изисква повече мощност на процесора освен оригиналното приложение. Това може да повлияе на изпълнението на заявки, които изискват голяма памет
  • Програмистите нямат контрол върху планирането на процесорното време, посветено на освобождаването на обекти, които вече не са необходими
  • Използването на някои реализации на GC може да доведе до спиране на приложението непредсказуемо
  • Автоматизираното управление на паметта няма да бъде толкова ефективно, колкото правилното разпределение / освобождаване на паметта

3. Реализации на GC

JVM има четири вида внедрения на GC :

  • Сериен колектор за боклук
  • Паралелен събирач на боклук
  • CMS Колектор за боклук
  • G1 Колектор за боклук

3.1. Сериен колектор за боклук

Това е най-простото изпълнение на GC, тъй като основно работи с една нишка. В резултат на това това изпълнение на GC замразява всички нишки на приложения, когато се изпълнява . Следователно не е добра идея да се използва в многонишкови приложения като сървърни среди.

Обаче имаше отлична беседа от инженерите на Twitter по време на QCon 2012 за работата на Serial Garbage Collector - което е добър начин да разберете по-добре този колектор.

Serial GC е събирачът на боклук по избор за повечето приложения, които нямат изисквания за време на малка пауза и работят на машини в стил клиент. За да активираме Serial Garbage Collector , можем да използваме следния аргумент:

java -XX:+UseSerialGC -jar Application.java

3.2. Паралелен събирач на боклук

Това е GC по подразбиране на JVM и понякога наричан Колектори за пропускателна способност. За разлика от Serial Garbage Collector , той използва множество нишки за управление на куп място . Но също така замразява други нишки на приложения, докато изпълнява GC .

Ако използваме този GC , можем да посочим максимални нишки за събиране на боклука и време на пауза, производителност и отпечатък (размер на купчината).

Броят на нишките на събирача на боклук може да се контролира с опцията на командния ред -XX: ParallelGCThreads = .

Целта за максимално време на пауза (интервал [в милисекунди] между два GC ) е посочена с опцията на командния ред -XX: MaxGCPauseMillis = .

Целта за максимална пропускателна способност (измерена по отношение на времето, прекарано в събирането на боклука спрямо времето, прекарано извън събирането на боклука) е посочена от опцията на командния ред -XX: GCTimeRatio =.

Максималният отпечатък на купчината (количеството памет на купчината, която програмата изисква по време на изпълнение) е посочен с помощта на опцията -Xmx.

За да активираме Parallel Garbage Collector , можем да използваме следния аргумент:

java -XX:+UseParallelGC -jar Application.java

3.3. CMS Колектор за боклук

В Едновременното Марк Sweep (CMS) изпълнението използва множество боклучар теми за събиране на боклука. Той е предназначен за приложения, които предпочитат по-кратки паузи за събиране на боклук и които могат да си позволят да споделят ресурсите на процесора с колектора за боклук, докато приложението работи.

Просто казано, приложенията, използващи този тип GC, реагират средно по-бавно, но не спират да реагират, за да извършват събирането на боклука.

Един бърз момент, който трябва да отбележим тук, е, че тъй като този GC е едновременен, извикването на явно събиране на боклук, като например използване на System.gc (), докато паралелният процес работи, ще доведе до неуспех / прекъсване на паралелния режим .

Ако повече от 98% от общото време е прекарано в CMS събиране на боклук и по-малко от 2% от купчината се възстановява, тогава OutOfMemoryError се хвърля от CMS колектора . Ако е необходимо, тази функция може да бъде деактивирана чрез добавяне на опцията -XX: -UseGCOverheadLimit към командния ред.

Този колектор също има режим, познат като инкрементален режим, който е остарял в Java SE 8 и може да бъде премахнат в бъдеща голяма версия.

За да активирате CMS Garbage Collector , можем да използваме следния флаг:

java -XX:+UseParNewGC -jar Application.java

От Java 9, CMS събирачът на боклук е остарял . Следователно JVM отпечатва предупредително съобщение, ако се опитаме да го използваме:

>> java -XX:+UseConcMarkSweepGC --version Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release. java version "9.0.1"

Освен това Java 14 напълно отказа от поддръжката на CMS:

>> java -XX:+UseConcMarkSweepGC --version OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0 openjdk 14 2020-03-17

3.4. G1 Колектор за боклук

G1 (Garbage First) Garbage Collector е предназначен за приложения, работещи на многопроцесорни машини с голямо пространство в паметта. Той е достъпен от JDK7 Update 4 и по-късните версии.

G1 колекторът ще замени CMS колектора, тъй като е по-ефективен от производителността.

Unlike other collectors, G1 collector partitions the heap into a set of equal-sized heap regions, each a contiguous range of virtual memory. When performing garbage collections, G1 shows a concurrent global marking phase (i.e. phase 1 known as Marking) to determine the liveness of objects throughout the heap.

After the mark phase is completed, G1 knows which regions are mostly empty. It collects in these areas first, which usually yields a significant amount of free space (i.e. phase 2 known as Sweeping). It is why this method of garbage collection is called Garbage-First.

To enable the G1 Garbage Collector, we can use the following argument:

java -XX:+UseG1GC -jar Application.java

3.5. Java 8 Changes

Java 8u20 представи още един JVM параметър за намаляване на ненужното използване на паметта чрез създаване на твърде много екземпляри на един и същ String. Това оптимизира паметта на купчината, като премахва дублирани String стойности в глобален единичен масив char [] .

Този параметър може да бъде активиран чрез добавяне на -XX: + UseStringDeduplication като JVM параметър.

4. Заключение

В този бърз урок разгледахме различните имплементации на JVM Garbage Collection и техните случаи на използване.

По-подробна документация можете да намерите тук.