[Java] 가비지 컬렉터 (Garbage Collector)

들어가면서

본격적으로 가비지 컬렉터에 대해서 얘기하기 전에 아래 내용을 이해해야 한다.

1
2
3
4
5
6
7
public class Main {
  public static void main(String[] args) {
    String a = new String("apple");
    String b = new String("banana");
    a = b;
  }
}

위와 같은 코드가 있을 때, 메모리 상황은 아래와 같이 표현할 수 있다. new 키워드로 생성된 인스턴스는 Heap에 저장되고, 스택에는 레퍼런스만 저장된다.

String a = new String("apple");
garbage-collector-1
String b = new String("banana");
garbage-collector-2
a = b;
garbage-collector-3

Heap 메모리에서 "apple"에 대한 레퍼런스가 없다. "apple"은 가비지가 되었고, 가비지 컬렉터는 이런 것들을 수집할 것이다.

Garbage Collector

가비지 컬렉터는 JVM의 실행 엔진 중 한 요소이다. 더이상 참조되지 않는 메모리를 가비지(garbage)라고 하며, 이들을 청소하는 역할을 한다. C 언어를 해봤다면 동적으로 할당받은 메모리를 free()를 통해 해제하는 과정이 필요하다는 것을 알 것이다. Java에서는 그것을 가비지 컬렉터가 알아서 한다.

Heap

가비지 컬렉터의 대상은 Heap 메모리이다. Heap 메모리는 아래와 같은 구조로 나뉘어 진다.

garbage-collector-heap

참고했던 oracle 문서에 따르면 Permanent generation도 존재하지만, java 8부터는 Metaspace로 대체되면서 없어졌다.

Process

  1. 새로운 객체는 Eden space에 배치된다. 처음에는 S0, S1 모두 비어있다.

    garbage-collector-process-1
  2. Eden space가 가득차면 minor garbage collection이 발생한다.

    garbage-collector-process-2

    2-1. minor garbage collection은 항상 Stop the world 이벤트를 발생시킨다. 이 작업을 마칠 때까지 모든 쓰레드가 멈춤을 의미한다.

    2-2. 참조되지 않는 객체를 마크하고 삭제한다. (mark and sweep)

    2-3. 참조되는 객체는 S0(survivor space)로 옮겨진다.

  3. 이후에 다시 Eden space가 가득차면, minor garbage collection이 발생한다.

    garbage-collector-process-3

    3-1. Eden space에서 참조되지 않는 객체를 삭제하고, 참조되는 객체는 S1(survivor space)으로 옮겨진다.

    3-2. S0에서 참조되지 않는 객체를 삭제하고, 참조되는 객체는 age가 증가하면서 S1으로 옮겨진다.

  4. 이후에 다시 Eden space가 가득차면, minor garbage collection이 발생한다.

    garbage-collector-process-4

    4-1. 참조되는 객체는 S0으로 이동하고, S1이 비워진다.

    4-2. 같은 과정이 반복되며, 계속해서 비워지는 survivor space가 바뀌는 것을 알 수 있다.

  5. 자주 참조되는 객체는 survivor space를 오가면서 age가 증가하는데, 특정 이상의 age를 가지는 객체는 Old generation으로 이동한다. 이를 Promotion이라 한다.

    garbage-collector-process-5

    5-1. Old generation은 Tenured generation이라 불리기도 한다

  6. Old generation까지 가득차면 major garbage collection이 발생한다.

참조

태그:

카테고리:

수정일자:

생성일자:

댓글 남기기