1. 개요

얼마전 GC 정책 중 UseParallelGC와 UseParallelOldGC에 대해 생각해 볼 기회가 있었다.

사실 -XX:+UseParallelOldGC가 -XX:+UseParallelGC의 관계는 다소 모호하다. 보통의 Java 6~7 시대에서 -XX:+UseParallelOldGC는 단순한 add-on parameter가 아니었다. 만약 그렇다면 -XX:+UseParallelOldGC는 반드시 -XX:+UseParallelGC와 같이 쓰여야 했을 것이다.
 
하지만 그렇지 않았다. -XX:+UseParallelOldGC는 엄연히 독자적인 GC 정책이었다. 한편  XX:+UseParallelOldGC를 사용하면 기본적으로 -XX:+UseParallelGC를 사용할 수 있었다.

2. default

그런데 Java 7 Update 4 이후부터는 XX:+UseParallelGC 사용시에도 -XX:+UseParallelOldGC를 default로 사용하게 된다.
 
* Java™ SE 7 Update 4 Update Release Notes
 
http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html
 
Parallel Old GC (-XX:+UseParallelOldGC) is now enabled by default whenever -XX:+UseParallelGC is enabled. To revert to the previous default behavior, use the option -XX:-UseParallelOldGC on the java command line.

그에 이어 Java 8로 오면서부터는 XX:+UseParallelOldGC에 대한 언급이 확 줄었다.

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref27
 
The parallel collector (also known as the throughput collector) performs minor collections in parallel, which can significantly reduce garbage collection overhead. It is intended for applications with medium-sized to large-sized data sets that are run on multiprocessor or multithreaded hardware. The parallel collector is selected by default on certain hardware and operating system configurations, or can be explicitly enabled with the option -XX:+UseParallelGC.

Parallel compaction is a feature that enables the parallel collector to perform major collections in parallel. Without parallel compaction, major collections are performed using a single thread, which can significantly limit scalability. Parallel compaction is enabled by default if the option -XX:+UseParallelGC has been specified. The option to turn it off is -XX:-UseParallelOldGC.
이제 그냥 편하게 -XX:+UseParallelGC만 쓰면 되고, UseParallelOldGC에 의해 수행되었던 역할을 굳이 끄고 싶을 때만 XX:-UseParallelOldGC을 사용하라고 한다. (물론 JDK 8 & Tomcat 8로 테스트 결과 XX:+UseParallelGC와 -XX:+UseParallelOldGC도 문제 없다)
 
결론적으로, Java 7 Update 4 이상이면 UseParallelGC와 UseParallelOldGC 중 어느 하나만 사용해도 결국 UseParallelOldGC 처럼 동작한다. 

 


3. ParallelGCThreads

얼마나 많은 스레드가 일을 할 것인가 정하는 옵션이다. 일반적으로는 다음과 같은 산식을 갖는다고 알려져 있다.

  • CPU가 8개 이하면 CPU 수만큼
  • CPU가 8개 초과면 (CPU X 5) / 8

4. Parallel vs. CMS

4-1. Parallel

  • 최대 처리량을 위한 GC 방식이다.
  • Mark, Sweep, Compact가 동시에 발생하여 상대적으로 멈춤시간이 크다.

4-2. CMS

  • Full GC시 멈춤 시간이 짧은 편이다.
  • Parallel 방식에 비해 처리량이 적은 편이고 더 많은 자원을 사용한다.

5. GC  튜닝 접근

5-1. GC 횟수 줄이기

  • Minor GC : 불필요하게 새로 생성되는 객체가 있는지 확인
  • Full GC : 응답시간을 줄여서 New -> Old로 넘어가는 객체 최소화

5-2. GC 시간 줄이기

GC 시간을 줄이기 위해서는 Compaction 시간을 줄이는 것이 관건이다. 그것은 곧 GC 후 살아있는 객체를 최소화하는 문제와 직결된다.

  • 적절한 캐시 혹은 메타 데이터 사용
  • 지연 로딩 처리 : 처음부터 로딩하지 않고 필요한 시점에 로딩하는 것이다.