[Java] Garbe Collector

Garbage Collector

stop-the-world

stop-the-world란 GC를 수행하기 위해 JVM이 어플리케이션 실행을 멈추는 것이다. stop-the-world가 발생하면 GC를 수행하는 스레드를 제외한 나머지 스레드는 작업을 멈추게 된다.

Reference Counting Algorithm

참조 카운트 알고리즘은 오브젝트 내에 참조 카운트가 있고 참조 카운트가 0이라면 수거를 해가는 방식이다. 이 방식은 참조 카운트가 0이 되면 GC가 수행된다. 참조 카운트만을 기준으로 GC의 수행 여부를 결정하기 때문에 순환참조의 영향으로 Memory Leak이 발생한다.

Mark-and-Sweep Algorithm

이 방식은 Root Set부터 시작해서 Root Set이 참조하는 관계를 추적해 Mark를 하고 Mark되지 않은 오브젝트들은 Sweep하는 방식이다. 이 방식은 참조되지 않는 오브젝트들을 해제만하기 때문에 Fragmentation의 문제가 있다.

Mark-and-Compact Algorithm

Mark-and-Sweep에서 Compact를 추가한 방식이다. Compact를 추가하였기 때문에 Sweep Phase 이후에 Compact를 진행하여 조각난 메모리들을 연속되게 적재시킨다. Fragmentation의 문제를 해결했다.

Copying Algorithm

이 방식도 Fragmentation의 해결을 위해 고안된 방법이다. 힙 메모리를 Active 영역과 Inactive 영역으로 나누어 Active 영역에만 오브젝트를 할당한다. Active 영역이 가득 차게 되면 GC를 수행하는데 이 때 참조되고 있는 오브젝트는 Inactive 영역으로 이동한다. 그 뒤엔 Active 영역에는 참조되지 않은 오브젝트만 남게 되는데 이 때 Active 영역을 비우고 Active 영역을 Inactive영역으로 바꾼다. 오브젝트들이 옮겨간 Inactive영역은 Active 영역으로 바뀐다. Active / Inactive 영역은 논리적인 구분일 뿐이다.

Generation Algorithm

이 방식은 Copying Algorithm 방식에서 두가지 측면을 고려하여 개선되었다.

  • 대부분의 새로 할당된 객체는 오랫동안 살아남지 못하고 GC의 대상이 된다.
  • 오래된 객체에서 새로운 객체로의 참조는 거의 없다.

그렇기 때문에 힙 영역을 Young Generation, Old Generation으로 나누어 구분짓는다. 기본적으로 Copying Algorithm의 방식을 채용하는데 Young Generation이 가득 차면 참조된 오브젝트만 Old Generation으로 넘기는 방식이다. Young Generation Old Generation이 가득 차게되면 full GC가 이루어지게 된다.

Young 영역은 3개의 영역으로 구분짓는데 Eden, Survivor1, Survivor2로 나뉘게 된다. 새로 생성된 오브젝트는 Eden 영역에 위치하며 살아남을 경우 Survivor 영역으로 이동한다. 이렇게 작업을 수행하면 Survivor 영역이 가득 차게 되는데 가득 차게 된다면 다른 Survivor 영역으로 참조되고 있는 오브젝트들을 이동시킨다. 그럼 기존의 Survivor 영역은 다시 비게 되고 이런 작업을 반복하다가 일정 횟수 이상 살아남은 오브젝트는 Old 영역으로 이동한다.

참조

https://medium.com/@joongwon/jvm-garbage-collection-algorithms-3869b7b0aa6f
https://d2.naver.com/helloworld/1329

Author: Song Hayoung
Link: https://songhayoung.github.io/2020/09/01/Languages/Java/garbeCollector/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.