본문 바로가기

Programing/JVM(Java, Kotlin)

[Java] 내가 사용하는 GC 알고리즘은 무엇일까?

자바에서는 보통 아래 다섯가지를 주요 GC 타입을 기술한다.
Serial Garbage Collector- S GC
Parallel Garbage Collector- P GC
CMS Garbage Collector- CMS GC
G1 Garbage Collector- G1 GC
The Z Garbage Collector- ZGC

웹에서 기본 CG를 찾아보면 자바 버전에 따라 달라졌음을 알 수 있다.

stackoverflow: Default garbage collector for Java 8

Java 7 - P GC       
Java 8 - P GC
Java 9 - G1 GC
Java 10- G1 G

시간대에 따라 힙의 증감 톱니바뀌는 다름을 알 수 있다.
트래픽이 적은 새벽 3시~8시에는 주기가 길고, 많은 주간~야간에는 짧음을 알 수 있다.

  • 새벽: 4:28 ~ 5:32 (1H 4') ~ 6:39 (1H 7')
  • 저녁: 22:49 ~ 23:08(19') ~ 23:18 (10') ~ 23:27 (9')

12H Heap 그래프

minor GC를 24시간으로 확대를 해서 관찰해보면 아래와 같다. (이날 배포가 1시쯤에 있어서 앞에 기록은 없다)

Minor GC 주기를 확인하기 위해 카운터를 확대해서 보면 아래와 같다.

낮시간대에는 10분에 한 번정도 minor CG가 이루어지고 있었다.

13:39
13:51
14:02
14:14
14:24
14:35
14:46

반면 새벽 시간대에는 50분 정도의 주기로 길어졌다.

03:41
04:29
05:33
06:40
07:31

GC가 수행하는 시간이 중요한데 peak가 88ms 정도로 심각할 정도는 아니다.

GC 알고리즘 확인

자바 애플리케이션을 실행할 대 명시적으로 GC를 지정했으면 그 알고리즘이 선택이 될 것이다.
jps -l 명령으로 조회가 되지만 나오지 않아서 ps 명령을 사용했다.


$ ps -elf | grep java
4 S webapp   27384 27311  1  80   0 - 1263398 -    Apr06 ?        00:21:28 java -server -Xms2g -Xmx2g -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -verbose:gc -Xloggc:/var/log/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log -Duser.timezone=Asia/Seoul -Dspring.profiles.active=live -Dsentry.environment=live -Dsentry.servername=ip-10-33-155-5 -Dsentry.release=1.0.5 -javaagent:/pinpoint-agent/pinpoint-bootstrap-2.0.1.jar -Dpinpoint.agentId=i-046ac710524c65dbd -Dpinpoint.applicationName=my-api -Dmetric.application=my-api -Dmetric.ebname=my-api-live-green -Dmetric.hostname=i-046ac710524c65dbd -jar my-api-1.0.5.jar

보다시피 G1(Garbage first) GC를 지정했다.

스위치가 없을 경우

jps -l

로 자바 프로세스의 PID를 조회후
jmap -heap [PID] 로 조회가 가능하다고 한다.

하지만 시도결과 아래와 같은 에러를 만났다.

jmap -heap 18989
Attaching to process ID 18989, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal$BsdDebuggerLocalWorkerThread.execute(BsdDebuggerLocal.java:169)
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal.attach(BsdDebuggerLocal.java:287)
at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:671)
at sun.jvm.hotspot.HotSpotAgent.setupDebuggerDarwin(HotSpotAgent.java:659)
at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:341)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.tools.jmap.JMap.runTool(JMap.java:201)
at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal.attach0(Native Method)