Java GC에 대해

wannabeking·2022년 7월 6일
0

Java

목록 보기
2/13
post-thumbnail

Java GC

  • Java는 JVM에서 GC가 자동으로 동작한다.
  • GC를 실행하기 위해 JVM이 어플리케이션 실행을 멈추는 stop-the-world가 발생하고 GC를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춘다.
  • GC 기법으로 세대 단위 쓰레기 수집 기법을 사용한다.
  • 세대 단위 쓰레기 수집 기법이란, 새롭게 할당된 영역일수록 금방 해제될 확률이 높다는 특성을 이용하여 각각의 객체를 할당된 시간에 따라 세대별로 구분하고 한 세대의 메모리 영역이 꽉차면 살아남은 객체들을 더 오래된 메모리 영역에 옮기는 것이다.
  • Young Generation (Eden, Survivor1, Survivor2), Tenured Generation (Old)으로 세대를 나눈다.

  • 위 그림에서 Eden, Survivor1, Survivor2 부분을 Young Generation이라고 하고 이 영역의 GC를 Minor GC라고 부른다.
  • Old 부분을 Tenured Generation이라고 하며 이 영역의 GC를 Major GC / Full GC라고 부른다.


Minor GC

  • Eden 영역은 자바 객체가 생성되자마자 저장되는 곳이다.
  • Minor GC가 동작하면 Eden 영역의 객체가 Survivor 영역으로 이동하고, Survivor 영역에 있던 객체들은 다른 Survivor 영역에 이동하게 된다.
  • 순서대로 설명하면 다음과 같다.
    1. Minor GC가 동작하면 Eden과 Survivor1의 살아남은 객체들을 Survivor2에 복사한다. (이전에 Survivor1에 복사했다고 가정)
    2. Minor GC가 동작하면 Eden과 Survivor2의 살아남은 객체들을 Survivor1에 복사한다.
    3. 이 과정을 반복한다.
  • 반복하다 보면 Survivor에는 오래 살아남은 객체들이 존재할 것이고 Survivor 영역이 꽉차면 이 객체들은 Old 영역으로 옮겨진다.
  • 만약 객체의 크기가 Survivor 영역의 크기보다 크다면 바로 Old 영역으로 이동한다.
  • 새로운 객체의 할당과 해제는 빈번하고 영역이 크기가 작기 때문에 자주 발생하지만 Major GC보다 빠르다.


Major GC / Full GC

엄밀히 따지자면 Major GC는 Tenured Generation 영역에서 발생하며 Full GC는 힙 메모리 전체에서 발생하지만 두 GC와 Minor GC로 크게 나누는 것 같다. (왜 같게 보는지는 모르겠다...)

  • GC가 동작하면 Old 영역에 있는 모든 객체들을 검사하면서 참조되고 있는지 확인한다.
  • 이때 mark-compact에서 변형한 기법들을 사용하는 것 같다. (여기까진 너무 deep하다...)
  • GC가 일어나면 접근 불가능한 메모리는 해제하고, 남은 메모리들을 시작 위치로 옮긴다.
  • Old 영역은 Young 영역보다 크게 할당하기 때문에 GC는 더 적게 발생하지만 Minor GC보다 느리다.


profile
내일은 개발왕 😎

0개의 댓글