본문 바로가기

개발

ZGC를 프로덕션에 적용해보자! (GC 튜닝 & STW & 최적화)

발단

최근, 노래하는하리보가 끊기거나 반응하지 않는다는 이슈가 너무 많아졌다.
왜 이런 증상이 발생하나 살펴보던 도중, GC가 원인이라는 것을 알아냈다.

피크 시간대에 STW (Stop-The-World)를 유발하는 Full GC가 발생함으로써, 작업들이 Timeout되거나 밀리게 된 것.
게다가 Full GC가 완료된 후, 미뤄진 작업들이 한번에 처리되면서 또 다른 Full GC가 발생했고... 이러한 문제로 인해 끊김과 무반응 이슈가 생겨난 것이다.

해결 방법은 없었나?

G1GC를 사용할 때는 STW 시간을 아무리 줄인다 해도, STW로 인해 발생하는 연쇄적인 Full GC를 막을 수 없었다. (STW 시간이 너무 길었기 때문)

여러가지 실험을 거친 후 내린 결론은 STW 시간이 매우 짧은 GC 알고리즘으로 (= ZGC) 변경하는 것이었다.

ZGC의 GC Pause time이 매우 짧은 것을 볼 수 있다.

(ZGC가 무엇인지에 대해서는 이 글을 참고하자)
(ZGC를 프로덕션에서 사용 중인 FLO 블로그도 참고하자)

적용

간단하다. 노래하는하리보Java 17을 사용하고 있기 때문에,

기존 플래그에 --XX:+UseZGC -XX:+ZUncommit를 추가하는 것으로 설정이 완료되었다.

java --XX:+UseZGC -XX:+ZUncommit -jar ...

적용 후 주의해야 할 점

클라우드의 OOM-Killer를 조심해야한다. ZGC는 colored pointers라는 기술을 사용하기 때문에, RES값이 비정상적으로 높게 보일 수 있다.
이로 인해 메모리가 부족한 것으로 오탐지되어 JVM 프로세스가 kill 될 수 있으므로, OOM-kill 당하지 않게 미리미리 처리 해주는 것이 좋다.