[TIL] JVM garbage collection

insightp25·2023년 2월 14일
post-thumbnail

'stop-the-world'

stop-the-world: JVM가 garbage collection(GC)를 실행 시 GC를 실행하는 스레드 외의 모든 스레드의 작업을 멈추는게 되는 것

Java 애플리케이션 성능을 최적화하기 위해 GC 튜닝이란 것을 수행할 수 있는데, GC 튜닝은 보통 이 stop-the-world의 시간을 줄이기 위한 것이다.


'weak generational hypothesis'

객체는 최초로 Eden 영역에 만들어지고, Survivor 영역으로 이동해 오래 살아남게 되면 다시 Old 영역으로 이동한다.

weak generational hypothesis란,

  • 대부분의 객체는 금방 접근불가 상태가 된다
  • 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다

는 가설이며, JVM에서는 이 가설에 근거해 힙의 물리적 공간을 Young 영역과 Old 영역으로 나눈다.

*그림의 'Tenured'는 Old 영역을 뜻한다

  • Minor GC: 새롭게 생성된 대부분의 객체가 위치한 Young 영역에 위치하게 되며, 이 영역에서 객체가 사라지는 것
  • Mjaor GC: Young 영역에서 살아남아 Old 영역으로 복사되었던 객체가 이 Old 영역에서 객체가 사라지는 것. 보통 Old 영역은 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC가 적게 발생한다.
    Permanent 영역(JDK 8부터 삭제되고 'Metaspace'로 대체되었으며 Method 영역이라고도 한다)은 객체나 억류(intern)된 문자열 정보를 저장하는 곳인데, 이 곳에서 GC가 발생해도 Major GC의 횟수에 카운트된다.

Old 영역에 있는 객체가 Young 영역의 객체를 참조하는 경우를 위해, Old 영역 내에 카드 테이블(card table)이라는 512바이트의 구조가 존재한다. 해당의 경우에 카드 테이블에 정보를 표시하며, Young 영역의 GC 실행 시 이 카드 테이블만 뒤져서 GC 대상 여부를 확인한다.


Young 영역에 대한 GC + 메모리 할당

Young 영역은 'Eden 영역'과 'Survivor 영역(2개)'로 총 3개의 영역으로 나뉜다. 이 곳에서 GC의 과정을 축약하자면:

  1. 새로 생성한 대부분의 객체가 Eden 영역에 할당
  2. Eden 영역에서 GC가 한 번 발생하고, 살아남은 객체는 Survior 영역 중 하나로 이동한다.
  3. 두 Survivor 영역 중 하나는 항상 비어있는 상태로 남아있으며, 두 Survivor 영역 중 한 곳을 가득 채웠다가 GC를 수행하고 살아남은 나머지 객체를 반대 Survivor 영역으로 모두 넘기고, 해당 Survivor 영역을 또 다시 채웠다가 GC를 수행하고 다시 원래 Survivor 영역으로 넘기는 같은 과정을 반복한다.
  4. 이 과정에서 계속 살아남은 객체는 Old 영역으로 이동한다.

JVM에서는 보다 빠른 메모리 할당을 위해 bump-the-pointer와 TLABs(Thread-Local Allocation Buffers)라는 기술을 사용한다.

  • bump-the-pointer: Eden 영역에 할당된 마지막 객체만 점검, 빠른 메모리 할당
  • TLABs: 멀티 스레드 환경에서 lock이 발생해 성능이 떨어지는 것(lock-contention)을 방지하고자, 각각의 스레드가 각각의 몫에 해당하는 Eden 영역의 작은 덩어리를 가질 수 있도록 하는 것



Old 영역에 대한 GC

Old 영역은 보통 데이터가 가득 차면 GC를 실행한다. JDK 7 기준으로 5가지 방식이 있다.

구분알고리즘장점단점기타 사항
Serial GCmark-sweep-compaction적은 메모리와 CPU 코어 개수가 적을 시 적합GC 처리 스레드 1개만 실행-
Parallel GC(/Throughput GC)mark-sweep-compactionGC 처리 스레드 여러 개(보다 빠른 객체 처리)메모리 사용량, 충분한 CPU 코어 개수 확보 필요-
Parallel Old GC(Parallel Compacting GC)mark-summary-compaction--Parellel GC와 비교하여 Old 영역의 GC 알고리즘만 상이, summary시 앞서 GC를 수행한 영역에 대해서 별도로 살아있는 객체 식별
Concurrent Mark & Sweep GC(CMS GC/Low Latency GC):initial mark-concurrent mark-remark-sweep빠른 성능CPU, 메모리 사용량. 조각난 메모리로 compaction작업시 긴 stop-the-world 시간G1 GC가 새로 등장하면서 사용하지 않음
G1(Garbage First) GCYoung의 세가지 영역에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식(가장)빠른 성능-Heap 영역을 region으로 구분, Java 9부터 기본 GC로 사용






참고 자료

profile
backend, data-streaming, AI

0개의 댓글