Java GC Type

Serial GC Parallel GC CMS GC G1 GC

CMS (Concurrent Mark Sweep)

Parallel Garbage Collection은 결과적인 효율(전체 시간 대비 STW 시간)은 좋지만 하나의 STW이 긴 편이다.
이를 해결하기 위해 CMS GC가 도입되었다.
CMS GC는 전체적인 성능이 비교적 조금 떨어질 수 있지만 STW로 인해 응답하지 못하는 시간이 길어지지 않도록 하는 것이 목표이다.

Java 9부터 deprecated 되었고, Java 14에서 drop 되었다.

Parallel vs CMS

Minor GC(young)의 경우 Parallel과 유사하다.
모든 thread가 Minor GC 수행 시 중단되고 GC 작업은 multi thread로 수행된다.

Major GC(old)의 경우 Parallel과 다르다.
CMS의 목적은 STW를 방지하는 것이고 이를 위해 짧은 STW를 제외하고는 GC를 application thread 수행과 동시에 수행된다.

  • GC로 인한 모든 thread의 STW가 최대한 발생하지 않도록

GC process

  • cms

Initial-Mark

여기서는 Old GC가 STW로 initial-mark를 진행한다.

Marking/Pre-Cleaning

initial-mark가 끝나면 application thread가 동작하면서 일부 CMS thread에서만 을 진행한다.

  • 이때부터 STW는 끝난 것이다.

이 때 hardware thread가 충분하면 CMS thread의 실행 overhead가 성능에 거의 영향을 미치지 않는다.
그러나 충분하지 않을 경우에는 application thread랑 CPU 경합을 벌이면서 성능에 영향을 미치게 된다.

Remark

initial-mark 이후에 marking/pre-cleaning 동안 누락되었을 수 있는 objects를 mark한다.

Concurrent Sweeping

모든 dead object의 memory를 free 한다.

CMS GC 특징

짧은 STW를 유지하기 위해 사용하는 concurrent 방식을 위해 parallel GC보다 10~20% 더 많은 heap을 필요로 한다.

  • heap이 부족해지기 전에 GC 작업이 완료될 수 있도록 tuning 하는 것이 중요하다.

Major GC가 진행되는 동안 Minor GC가 발생할 수 있다.
이런 경우 Major GC가 중단되고, Minor GC가 완료된 이후에 다시 시작된다.

기본적으로 parallel GC에 비해 application thread가 멈추는 시간이 짧다.

  • 그렇지만 GC에 소모되는 시간은 더 길다.
  • GC cycle 동안 application 처리율은 감소한다.
  • GC가 객체를 추적해야하므로 CPU/memory를 더 많이 쓴다.

CMF (Concurrent Mode Failure)

할당률이 급증하면 young GC 시에 조기 승격(premature promotion)이 발생하고 승격된 객체가 너무 많아 tenured 영역도 부족한 상태가 벌어질 수 있다.
이런 현상을 CMF라고 하고 JVM은 어쩔 수 없이 full STW를 유발하는 Parallel GC로 돌아간다.

  • 새로 승격된 객체를 old에서 처리하여 memory를 확보 할 시간도 없이 새로운 객체가 생성되는 현상.

CMS는 compaction을 하지 않기 때문에 비어잇는 공간들(fragmentation)이 새로운 객체를 할당하기 위한 공간보다 작을 수 있고, 이것도 CMF로 가는데 영향을 미칠 수 있다.

  • fragmentation은 예측 불가능하기 때문에 더 문제

Parallel GC로 가면 STW의 시간이 길어지기 때문에 CMS를 쓰는 장점이 사라진다.
CMF가 자주 일어나지 않게 하려면 tenured가 차기 전에 CMS GC가 돌아야 한다.
CMS GC는 tenured가 default 75%가 차면 도는데 값을 지정할 수 있다.

command

-XX:+UseConcMarkSweepGC으로 사용할 수 있다.

  • java -XX:+UseConcMarkSweepGC -jar demo.jar

reference

  • https://www.baeldung.com/jvm-garbage-collectors
  • https://www.informit.com/articles/article.aspx?p=2496621&seqNum=4
  • https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html
  • Optimizing Java, chapter7