61 lines
4.1 KiB
Markdown
61 lines
4.1 KiB
Markdown
|
||
[[GC]]
|
||
GC 튜닝이 필요한 이유: [[STW (Stop The World)]]
|
||
|
||
- STW가 발생하면 [[GC]]를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춤.
|
||
- GC작업이 완료된 이후에야 중단했던 작업을 다시 시작됨.
|
||
- GC가 자주 발생하거나, 또는 시간이 오래 걸리는 경우는 어플리케이션이 비정상 동작하는 시간이 길어진다는 의미이기 때문에 대게의 경우 ==gc 튜닝이란 STW 시간을 줄이는 것을 의미==
|
||
|
||
### **GC 튜닝의 주의점**
|
||
|
||
그런데 GC 튜닝에 있어서 꼭 명심해야 하는 점이 있다.
|
||
|
||
**첫째는, GC 튜닝 옵션은 서비스의 특징 마다 적정 값이 다르다는 것이다.**
|
||
|
||
예를 들어 '누가 이 옵션값을 썼을 때 성능이 잘 나왔으니 우리도 이렇게 적용하자.' 라고 생각하면 절대 안 된다.
|
||
|
||
왜냐하면 서비스 주제와 특징마다 생성되는 객체의 크기도 다르고 살아있는 기간도 다르기 때문이다.
|
||
|
||
따라서 별도의 성능 모니터링을 통해 어느 지점에서 GC의 STW 문제가 나는지 **서비스마다 제각각 파악**하여 GC 튜닝을 진행할 필요가 있다.
|
||
|
||
**둘째는, GC 튜닝은 가장 마지막에 하는 작업이라는 것이다.**
|
||
|
||
GC 튜닝은 필요한 선행 지식과, 신경써야할 요소, 리스크에 비해서 얻어가는 부분이 너무 적기 때문에, GC를 건드리는 것보다 애플리케이션 코드로써 메모리 최적화를 더 신경 쓸것을 권장하는 의견도 있다.
|
||
|
||
GC 튜닝을 왜 하는지 근본적인 이유를 생각해보자.
|
||
|
||
일반적으로 Java에서 생성된 객체는 가비지 컬렉터가 처리해서 지운다.
|
||
|
||
즉, 생성된 객체가 많으면 많을수록 가비지 컬렉터가 처리해야 하는 대상도 많아지고, GC를 수행하는 횟수도 증가한다는 말이다. 그리고 GC의 수행 횟수가 늘어나면 STW 횟수도 많아지니 성능에 영향이 가게 된다.
|
||
|
||
따라서 GC 자체를 튜닝 하기 이전에 먼저 코드 단에서 **쓸모없는 객체 생성을 줄이는 리팩토링 작업을 먼저** 하는 것이 근본적인 해결법이 된다.
|
||
|
||
예를들어 ~~String~~ 대신 ~~StringBuilder~~나 ~~StringBuffer~~를 사용하는 거나, 로그를 최대한 적게 쌓도록 하는 등 임시 메모리를 적게 사용하도록 해주는 것이 먼저이다.
|
||
|
||
그리고 리팩토링 작업과 어플리케이션 메모리 조정을 해도 여전히 성능에 문제가 생기면 그제서야 GC 튜닝을 진행한다.
|
||
|
||
다시 말하자면 GC 튜닝은 자바 어플리케이션 성능 향상 작업에서 가장 마지막에 하는 작업이라는 것을 잊지 말자.
|
||
|
||
### **GC 튜닝의 목표**
|
||
|
||
**GC 튜닝**이란, 성능상 이슈를 일으키기 쉬운 GC에 대하여 최적화를 진행 하는 것을 말한다.
|
||
|
||
GC 튜닝의 목표의 핵심은 [[Minor GC]] 보다 Stop-The-Wold 시간이 긴 [[Major GC]]의 관리이다.
|
||
|
||
**첫째는, Old 영역으로 넘어가는 객체의 수 최소화하기 이다.**
|
||
|
||
위에서 살펴봤듯이, Old 영역의 크기는 Young(New) 영역의 크기보다 훨씬 거대하다.
|
||
|
||
따라서 Old 영역의 GC는 Young(New) 영역의 GC에 비해 상대적으로 시간이 오래 소요되기 때문에, 애초에 Old 영역으로 이동하는 객체의 수를 줄이면 Full GC가 발생하는 빈도를 많이 줄일 수 있게 된다.
|
||
|
||
이말은 즉, **Young(New) 영역의 크기를 잘 조절**하여 Old 영역으로 넘어가는 빈도를 줄이면 큰 효과를 볼 수 있다는 뜻이다.
|
||
|
||
**둘째는, Full GC 시간 줄이기 이다.**
|
||
|
||
Full GC의 실행 시간은 상대적으로 Minor GC에 비해 길기 때문에, Old 영역의 크기를 적절하게 설정하는 것도 하나의 방법이다.
|
||
|
||
그렇다고 Old 영역의 크기를 막 줄여버리면 자칫 OutOfMemoryError가 발생하거나 Full GC 횟수가 늘어날 수도 있다.
|
||
|
||
반대로 Old 영역의 크기를 늘리면 Full GC 횟수는 줄어들지만 실행 시간이 늘어나게 된다.
|
||
|
||
즉, GC 튜닝의 관건은 이 둘 사이를 잘 아우르는 적정 범위를 찾는 것이라 할 수 있다. |