28 Mayıs 2020 Perşembe

Concurrent Mark Sweep Garbage Collector - Java 8 İçin Belki Kullanılabilir

Giriş
Yazı uzun bu yüzden kısaca özetlemek gerekirse
- Young Generation için "Stop the World" emri verilir ve Paralel Mark Copy (Scavenge) kullanır. Yani nesne başka bloğa taşınır
- Old Generation için eğer mecbur değilse "Stop the World" emri verilmez ve Mark Sweep kullanır. Yani nesne olduğu yerde bırakılır. Aynı bloktaki nesneler arasında boşluklar oluşur. Kullanmak için şöyle yaparız
-XX:+UseConcMarkSweepGC  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xms1024m       -XX:+PrintCommandLineFlags -jar foo.jar
CMS vs Paralel Collector
CMS ve Paralel Collector bence Young Generation için aynı mantıkta çalışıyor. Her ikisi de "Stop the World" emrini veriyor ve paralel olarak işi hızlıca bitirmeye çalışıyor. Ancak CMS Minor GC işlemini çok daha sık yapıyor, Ayrıca ParNew içinde Old Generation'a bir callback gönderiyor.

Esas fark Old Generation'da ortaya çıkıyor. Paralel Collector, Major GC işleri için de "Stop the World" emri verirken, CMS major GC için concurrent yani uygulama thread'leri ile birlikte çalışarak "Stop the World" emrini mümkün olduğunca az vermeye çalışıyor.

Java 9 ve Ötesi
Java 9 ile CMS kullanmaya çalışınca yani şöyle yaparsak
XX:+UseConcMarkSweepGC
bize uyarı veriyor. Uyarı şöyle
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.
Bu GC Java 14 ile tamamen kaldırıldı. Açıklaması şöyle.
As of Java 9, the CMS garbage collector has been deprecated. Therefore, JVM prints a warning message if we try to use it:
...
Moreover, Java 14 completely dropped the CMS support:
Yerine Ne Kullanabiliriz ?
- Java 9 için G1 kullanılabilir
- Java 11,12 için Z kullanılabilir

Law Pause Ne Demek
Bu Garbage Collector "Low Pause" algoritmalardan bir tanesi. Stop the World emrini mümkün olduğunca az veriyor. Açıklaması şöyle.
The Concurrent Mark Sweep (CMS) collector is designed to be a lower latency collector than the parallel collectors. The key part of this design is trying to do part of the garbage collection at the same time as the application is running. This means that when the collector needs to pause the application's execution it doesn't need to pause for as long.

CMS uses the parallel stop-the-world mark-copy algorithm in the Young Generation and concurrent mark-sweep algorithm in the Old Generation.
Yani işlemci ve belleği daha fazla kullanarak, daha az Stop the World emrini veriyor. Açıklaması şöyle
It's designed for applications that prefer shorter garbage collection pauses, and that can afford to share processor resources with the garbage collector while the application is running.

Simply put, applications using this type of GC respond slower on average but do not stop responding to perform garbage collection.
Footprint
Açıklaması şöyle. Parallel Collector 'a göre daha fazla bellek harcar ancak karşılığında daha kısa duraklama (Low Pause) sağlar.
This CMS collector requires more footprint than Parallel Collector and it has more data structures to take care of. It has less throughput than the Parallel Collector but the advantage is it has smaller pauses than the Parallel Collector. This collector is the best-used collector for all the general Java applications
CMS Collector Belleği İşletim Sistemine Geri Verir
Açıklaması şöyle. Ancak bir kaç full GC işleminden sonra geri verir.
Serial and ConcMarkSweep are also shrinking garbage collectors and can scale memory usage in JVM vertically. But in comparison to G1, they require 4 Full GC cycles to release all unused resources.
2. CMS Nedir
Açıklaması şöyle
It attempts to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads. It uses the parallel stop-the-world mark-copy algorithm in the Young Generation and the mostly concurrent mark-sweep algorithm in the Old Generation.
3. Young Generation - Mark Copy 
Young Generation çalışırken "Stop the World" emri verilir. Mark-copy olduğu için yaşamasına karar verilen nesneler başka bloğa taşınır

Young Generation için Serial veya Parallel seçenekleri ile çalıştırılabilir.

3.1. Serial Seçeneği - Kullanmayın
Serial için şöyle yaparız. UseParNewGC'nin başında eksi var. Bu yöntem deprecated olarak işaretli ve Java 9 ile de kaldırıldı. Dolayısıyla kullanmamak lazım
-XX:+UseConcMarkSweepGC  -XX:-UseParNewGC
3.2. UseParNewGC Seçeneği  - parallel copying collector
Eğer sadece UseConcMarkSweepGC belirtilirse bu seçenek etkinleştirilmiş varsayılır. Açıklaması şöyle.
UseParNewGC A parallel version of the young generation copying collector is used with the concurrent collector (i.e. if -XX:+ UseConcMarkSweepGC is used on the command line then the flag UseParNewGC is also set to true if it is not otherwise explicitly set on the command line).
Bu seçeneği illaki belirtmek istersek şöyle yaparız.
XX:+UseConcMarkSweepGC -XX:+UseParNewGC
Açıklaması şöyle
The parallel copying collector (Enabled using -XX:+UseParNewGC). Like the original copying collector, this is a stop-the-world collector. However this collector parallelizes the copying collection over multiple threads, which is more efficient than the original single-thread copying collector for multi-CPU machines (though not for single-CPU machines). This algorithm potentially speeds up young generation collection by a factor equal to the number of CPUs available, when compared to the original singly-threaded copying collector.
Bu yüzden GC loglarında şuna benzer bir çıktı görürüz
[GC (Allocation Failure) ...  [ParNew: ....]
Açıklaması şöyle
Parallel New (ParNew) Collector (invoked by "-XX:+UseConcMarkSweepGC" option) - The ParNew collector for Young generation uses the "Copy (also called Scavenge)" algorithm parallelly using multiple CPU processors (multiple threads) in a stop-the-world fashion.

The ParNew collector for Young (new) generation uses the same algorithm as the PS collector, except that it has an internal 'callback' that allows an old generation collector to operate on the objects it collects (really written to work with the concurrent collector), as described by Jack Shirazi in "Oracle JVM Garbage Collectors Available From JDK 1.7.0_04 And After".

The ParNew collector for Young generation can be identified in GC log messages with the "ParNew" label, as in this example: "ParNew: 1068K->63K(1152K)".

In JVM 9 and older releases, the ParNew collector for Young generation can be invoked explicitly using the "-XX:+UseParNewGC" option. But this option has been removed from JVM 10.
4. Old Generation - Concurrent Mark Sweep
Old Generation için uygulama ile eş zamanlı çalışarak "Stop the World" emrinin mümkün olduğunca az olmasına uğraşır. Mark-sweep olduğu için yaşamasına karar verilen nesneler oldukları yerde bırakılırlar. Yani başka bloğa veya yan yana olacak şekilde yer değiştirmez. Aynı bloktaki nesneler arasında boşluklar oluşur.

Bu Garbage Collector Java 9'dan itibaren kullanılmamalı. Açıklaması şöyle.  Java 9'dan itibaren G1 artık en çok tercih edilen garbage collector.
The Concurrent Mark Sweep (CMS) collector has been deprecated since Java 9...

Hiç yorum yok:

Yorum Gönder