JAVA

JVM GC(Garbage Collection)

icedstone 2025. 4. 19. 16:26
반응형

C언어의 경우 malloc/free 를 통해서 프로그래머가 직접 메모리를 할당하고 해제해주지만 JVM의 경우에는 메모리를 알아서 관리해주고 있기 때문에 개발자가 직접 관리할 필요가 없어진다.

 

JVM에 다양한 메모리 영역이 존재하는데 그 중에서도 Heap영역에서 다음과 같이 GC가 동작한다.

Eden, Survivor, Old 영역들이 존재하는데 간단하게 객체가 생성(new Object()) 되면 Eden Space에 생겨난다.

그러고 나서 아직 참조가 되고있는 객체 더이상 참조 되지 않는 객체를 분류한다. 위의 그림에서 Object2가 Mark되어지고 MinorGC에 의해서 메모리 할당이 해제된것으로 보면 된다.

그렇게 생존한 객체들이 존재하는 Survivor영역을 왔다갔다 하면서 오래 살아남은 객체는 Old Generation으로 넘어가게 되고 추후 MajorGC가 동작할 때 확인하는 대상이 된다.

 

GC가 동작할 경우 STW(Stop The World)가 발생하게 되는데 GC를 제외한 모든 쓰레드가 동작을 멈추기 때문에 GC가 벌어지는 동안 그 어떤 동작도 불가능하다.(GC의 진화과정을 보면은 이 STW시간을 최소화하려는 노력을 엿볼 수 있다. 운영상 튜닝 과정도 마찬가지로 이 시간을 최소화하기위한 설정이 많다.)

 


같이 알아 두면 좋을 만한 내용

- Weak Generational hypothesis (David Ungar)

'대부분의 객체는 금방 죽는다.' 그래서 Young Generation에서 빠르게 Minor GC가 발생하고 그래도 메모리 영역이 부족하면 Old Generation에서 Major GC가 발생하게 된다.

 

- Mark And Sweep Algorithm

GC가 사용하는 가장 기본 적인 알고리즘이다. 영역을 Mark하고 삭제하게 되는데 메모리가 파편화되는 문제가 있어서 해결책으로 나온게 Mark And Compact Algorithm이다.

 

반응형

 

 

G1GC

The first focus of G1 is to provide a solution for users running applications that require large heaps with limited GC latency. This means heap sizes of around 6 GB or larger, and a stable and predictable pause time below 0.5 seconds.
- 오라클 공식 문서

공식 문서 내용을 보면 대용량 heap size에서 0.5초 이내로 STW가 발생하는걸 목표로 하고있다. heap이 작은 application에서는 G1GC 사용을 권장하지 않으니 참고해두면 실무에서 적용하기 좋을 것이라 생각된다.

 

그러면 어떻게 STW 시간을 최소화 하고 있는가?

이전 세대의 GC에서는 메모리를 모두 훑어서 garbage를 정리하는 방식이다. G1은 메모리를 여러개의 작은 region으로 나누고 각 영역별로 효율적으로 수집할 곳을 선택한다.

garbage가 많은 영역을 미리 알고, 정리를 하기 때문에 STW를 짧게 가져갈 수 있게 된다. (그렇기에 G1 - Garbage First 라고 명칭한다)

* jdk7부터 사용 가능하며 jdk9부터는 default GC이다.

ZGC

목표: 기존 GC의 경우 수십~수백 ms의 STW 조차도 대규모 실시간 서비스에는 치명적이기 때문에 시간을 극도록 줄이기 위하여 설계됨

 

기본적으로 기존 GC의 경우, 객체가 참조가 수정되면서 GC 중단이 필요하다.

예전에는 48비트 공간만을 활용해왔으나 64비트의 머신에서는 사용하지 않는 메모리 공간이 발생하였고, ZGC에서는 이 공간을 적극 활용하여 객체가 이동되는 순간에도 STW되지 않고 사용할 수 있도록 설계되었다.

* 일부 서버의 경우에는 ZGC사용이 불가능하다.

반응형