CMS 튜닝
: CMS는 튜닝이 매우 까다로운 GC이며, CMS 플래그의 가짓수는 방대하므로 다음의 안티 패턴의 늪에 빠지지 않도록 유의하며 사용해야한다.
- 스위치 만지작거리기
- 민간 튜닝
- 숲을 보지 못하고 나무만 보는 형태
처리율(Throughput) 관련 튜닝을 고려할 때, CMS 수집이 일어나면 코어의 절반은 GC에 할당되므로 애플리케이션의 처리율은 그만큼 절반이 날아간다. 이 때, CMF(Concurrent Mode Failure) 직전의 수집기 상태를 살펴보는 것은 중요한 지표를 가져다 준다. CMS 직후 새로운 CMS가 시작되는 Back-To-Back 현상은 CMS가 얼마 못 가 고장날거라는 신호이다. 애플리케이션 메모리 할당 속도가 회수 속도를 능가하며 CMF가 발생된다.
이러한 Back-To-Back 현상은 전체 애플리케이션의 실행 처리율을 50%나 떨어뜨린다. 성능 엔지니어는 튜닝 시 이런 상황이 발생해도 괜찮은지 고민해보고, 괜찮지 않다면 코어 수를 늘리는 해결 방안을 모색해야 할 것이다.- CMS 중 GC에 할당된 코어 수는 다음의
-XX:ConGCThreads=<n>
플래그로 설정할 수 있다. - 디폴트 설정 상태에서 GC 스레드 수를 줄인다면, 부하 급등 시 애플리케이션의 회복력이 떨어져 CMF에 취약해지는 상황을 초래할 수 있음에 유의하자.
- CMS 중 GC에 할당된 코어 수는 다음의
CMS에서 STW는 다음의 두 단계,
- Initial Mark: GC 루트가 직접 가리키는 내부 노드를 마킹한다.
- Remark: 카드 테이블을 이용해 조정 작업이 필요한 객체를 식별한다.
에서 이루어 진다. 따라서 CMS가 한 번 일어날 때마다 애플리케이션은 반드시 2번 멈추게 되는데, 세이프포인트에 예민한 저지연 애플리케이션에서는 중요한 영향을 미치게 된다.
다음의 두 플래그를 동시 적용하자.-XX:CMSInitiatingOccupancyFraction=<n>
: CMS 초기 점유율로, CMS가 언제 수집을 시작할지 설정하는 플래그이다. 여기서 지정된 크기 (Default:75%)의 힙 영역이 찼을 때 최초의 CMS가 시작된다.
(참고) CMS가 실행되면 영 수집을 통해 올드 영역으로 승격되는 객체들을 수용할 공간이 필요하다.-XX:+UseCMSInitiatingOccupancyOnly
: 이 플래그를 설정하면 초기 점유 공간을 동적 크기 조정하는 기능이 꺼지므로 위 플래그(CMSInitiatingOccupancyFraction)를 적용하지 않는다면 함부로 켜지 말아야 한다. 할당률이 심하게 튀는 CMS 애플리케이션의 경우 CMSInitiatingOccupancyFraction 매개변수 값을 줄임으로써 여유 공간을 늘이고, 능동적 크기 조정(adaptive sizing)기능을 끄는 전략을 구사함으로써 CMS GC를 자주 일으키더라도 CMF를 줄일 수 있을 것이다.
단편화로 인한 CMF
: CMS가 관리하는 프리 리스트로 인해 힙 단편화로 인한 CMF 발생 정보를 예측하는 방법이 존재한다.
: 다음의 플래그(-XX:PrintFLSStatistics=1
)를 추가하면 GC 로그에 다음의 정보가 추가적으로 표기된다.
Total Free Space: xxx
(총 Free 공간)
Max Chunk Size: xxx
(최대 청크 크기)
Number of Blocks: xxx
(블록 갯수)
Av. Block Size: xxx
(평균 블록 크기)
Tree Height: xx
(트리 높이)
: 평균 블록 크기와 최대 청크 크기를 보고 메모리 청크의 크기 분포를 대략 짐작 할 수 있다.
또한, 크기가 큰 Live 객체를 Tenured 영역으로 옮길 때 그만한 크기의 청크가 바닥난 경우, GC Promotion이 악화되어 이는 CMF로 이어질 것이다. 그러면 JVM은 Parallel GC로 돌아가 Heap을 압착하고 프리 리스트를 병합하며 STW 시간은 길어진다. 이러한 정보들은 긴 STW이 임박했음을 미리 알수 있고, 센섬같은 툴을 이용하면 CMF에 근접했다는 사실을 자동 감지할 수 있다.
'개발언어 > JAVA' 카테고리의 다른 글
GC Algorithm and Garbage Collectors (Java Performance Fundamental) (0) | 2021.04.29 |
---|---|
Parallel GC 튜닝 (Java Optimization) (0) | 2021.03.28 |
GC 튜닝 (Java Optimization) (0) | 2021.03.22 |
GC Logging (Java Optimization) (0) | 2021.03.21 |
JVM miscellaneous (Java Optimization) (0) | 2021.03.21 |