[JVM] G1 Collector - 큰 객체 할당, TLAB 튜닝

2021. 12. 16. 16:54 JAVA/JVM

크다? JVM의 TLAB 크기에 좌우
TLAB 이란?  
TLAB : Thread Local Allocation Buffer , 스레드 로컬 할당 버퍼
- 에덴 내에 있는 한 영역
- 스레드 마다 할당되는 객체 버퍼
- 하나의 스레드가 처리할 수 있는 객체의 최대 크기
- 각 스레드마다 스레드 로컬에 할당되므로, 동기화에 신경쓰지 않아도 된다. 
- TLAB에 할당되지 못하는 크기가 큰 객체들은 TLAB 밖에 할당된다.
- TLAB 밖에 할당된 객체들은 스레드 동기화등 여러가지 절차가 추가적으로 필요하기 때문에 처리하는데 TLAB 안에 있는 객체보다 처리가 느리다. 

TLAB이 가득차면, 일정 크기의 객체는 더이상 TLAB안에 할당될 수 없다. 
이 시점에서 JVM에게는 두 가지 선택사항이 있다. 
1) TLAB 을 새로 할당
2) 기존 TLAB 유지, 힙에 객체 할당 (느려짐)

예를들어, 100KB의 TLAB이 있을 경우, 70KB가 이미 할당되어있다면 남은 30KB의 동작에 대해, 다음 객체가 35KB 일 경우 TLAB 을 버리고 0KB 부터 다시 시작하던가, 해당 35KB객체를 힙에 할당하고 30KB 보다 작은 객체가 남은 공간에 할당되기를 기다릴 수 있다. 

큰 객체를 많이 할당하는 어플리케이션, 에덴의 크기에 비해 상대적으로 스레드의 개수가 많은 어플리케이션은 TLAB 튜닝으로 상당한 이익을 얻을 수 있다.

-XX:-UseTLAB
- TLAB의 사용을 중지한다. TLAB 은 잘 사용할 수록 좋기 때문에, 권장하지 않는다.


최적의 TLAB 크기 구하기
- 정확한 예측 불가
1) TLAB 의 바깥쪽에 할당이 일어나는지 TLAB 할당을 모니터링한다
2) 상당수가 TLAB 밖에 할당되면 할당되고 있는 객체의 크기를 줄이거나, TLAB 크기 조절을 해야한다.

1) TLAB 모니터링
- JFR : Java Flight Recorder
- JFR 은 다른 도구보다 TLAB 할당을 모니터링하는데 더 강력하다
- TLAB 안에 할당되는 전체 메모리, TLAB 바깥에 할당되는 메모리의 크기를 확인할 수 있다. 
- 할당된 객체들의 최대 크기, 평균 크기, 최소 크기들을 알 수 있다. 
- TLAB 바깥에 할당된 메모리의 크기가 너무 많다면, 바깥에 할당된 객체의 최대 크기 및 평균 크기를 확인하고, 해당 객체들을 TLAB 안에 포함할 수 있도록 TLAB의 크기를 늘려주면 좋다. 

2) TLAB 크기 조절
- TLAB 밖에 객체를 할당하면 시간이 많이 걸린다
- 항상 TLAB 밖에 할당되는 특정 오브젝트 타입이 있다면 해당 프로그램 코드 변경이 최선이다.
- 코드 변경이 불가능하다면, TLAB의 크기를 변경해서 해당 오브젝트를 TLAB에 할당할 수 있다.
TLAB의 크기는 에덴의 크기를 기반으로 하므로 에덴의 크기가 늘어나면 자동으로 TLAB의 크기도 늘어난다. (디폴트 전략)

-XX:TLABSize=N (default : 0)
디폴트 값이 0인 이유는, 에덴의 크기가 늘어나면 자동으로 TLAB의 크기가 증가하는 전략이 디폴트이기 때문이다.
TLAB 의 초기 크기만 설정한다. 에덴의 크기가 증가하면 따라서 증가함. 
GC가 발생할 때마다 에덴의 크기가 변경되므로 TLAB의 크기도 변경된다
GC가 발생할 때마다 크기가 변경되는 것을 방지하려면 -XX:-ResizeTLAB을 추가해야한다.
TLAB 을 튜닝할 때는 크기가 계속 변경되면 하기 힘드므로, 추가하는 것이 좋다.

-XX:TLABWasteTargetPercent=N
100KB의 TLAB중 30KB의 남은 공간에 대해 두 가지 선택을 할 수 있다고 했다.
30KB의 남은 공간에 작은 인스턴스가 할당될때까지 기다리든지, 버리고 새로 시작하든지. 
그 경계값을 지정해주는 플래그이다.

-XX:TLABWasteIncrement=N ( default :4 )
TLAB 바깥에 할당이 이루어 질때마다 TLABWasteTargetPercent의 값을 N씩 증가시킨다. 
이는 TLAB이 버려질 가능성을 점점 높혀서 인스턴스가 계속 TLAB 바깥에 할당되는 것을 방지한다.



TLAB 튜닝 요약
JFR 모니터링을 통해 TLAB 바깥에 얼마나 많은 메모리가 할당되는지 확인하고,
객체들의 평균,최대 크기를 확인한다음에
TLAB 의 크기를 평균 객체들의 크기로, 또는 조금 더 크게 조절하고
또 다시 모니터링 하고!
TLAB 바깥에 얼마나 많은 메모리가 할당됬는지 또 확인하고.. 반복!
TLAB 바깥에 메모리가 많이 할당될수록 느려진다!