[Java] Garbage Collector


Garbage Collector (가비지 컬렉터)

가비지(Garbage)란?

  • 정리되지 않은 메모리
  • 유효하지 않은 메모리 주소.
int[] array = new int[3];

array[0] = 1;
array[1] = 10;
array[2] = 20;

//새로운 String 타입의 배열을 만들어서 array가 새로운 배열을 가리키게함.
array = new String{'가','나','다','라','마'};

이때 기존의 array 가 가리키고 있던 int타입의 3칸짜리 배열은 주소를 잃어버려서 사용할수 없는 메모리가 된다.(정리되지 않은 메모리)

이를 자바에서는 가비지(Garbage)라고 부른다.

다른 예시

public class Garbage {
    public static void main(String[] args) {
        String str = "asdf";
        str += "qwer";
        System.out.println(str);
    }
}

image

문자열 더하기 연산이 수행되는 과정에서(String은 불변객체 이므로) 기존에 있던 “asdf”스트링에 “qwer”을 덧붙이는 것이 아니라, 문자열에 대한 더하기 연산이 수행된 결과가 새롭게 heap영역에 할당된다.

가비지 컬렉터란?

가비지 객체의 메모리를 해제시킨다.

쓰레기 객체를 효과적으로 처리하는 작업을 GC 라고 합니다. JVM의 가비지 컬렉터는 정리되지 않은 채로 남겨져 있는 메모리들을 다른용도로 사용할 수 있게 메모리 해제를 시키는 프로그램이다.

GC 과정

GC의 과정을 Mark and Sweep이라고도 한다. GC가 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾는 과정이 Mark 라고 한다. 이 과정에서 Stop the world가 발생한다. 이후 Mark 되어있지 않은 객체들을 힙에서 제거하는 과정이 Sweep 이다.

Stop the world는 GC 실행을 위해 JVM이 애플리케이션 실행을 멈추는 것이다.

Minor GC와 Major GC

JVM의 Heap은 Young, Old, Perm 세 영역으로 나뉜다. Young 영역에서 발생한 GC를 Minor GC, 나머지 두 영역에서 발생한 GC를 Major GC(Full GC)라고 한다.

  • Young 영역 : 새롭게 생성한 객체가 위치, 대부분의 객체가 금방 unreachable 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다가 사라진다.
    • eden 영역 : 메모리가 생성되면 객체가 여기 지정되고, Eden 영역에 데이터가 어느정도 쌓이면, 이 영역에 있던 객체가 어디론가 옮겨지거나 삭제된다. 이 때 옮겨가는 위치가 survivor 영역이다.
    • Survivor1,2 영역 : 두영역중 하나는 비어있어야된다. 비어이있는 영역에 Eden영역에 있던 객체가 할당된다. survivor 영역이 가득차게 되면 GC가 되면서 Eden 영역에 있는 꽉찬 객체와 꽉 찬 survivov 영역에 있는 객체가 비어있는 survivor영역으로 이동하게되고 그러다가 더 큰객체가 생성되거나 더이상 young 영역에 공간이 남지 않으면 old영역으로 이동한다.
  • Old 영역 : Young 영역에서 reachable 상태를 유지해 살아남은 객체가 여기로 복사된다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다.
  • Perm 영역 : Method Area라고도 한다. 클래스와 메소드 정보와 같이 자바 언어 레벨에서는 거의 사용되지 않는 영역이다.

가비지 컬렉터가 실행되는 시점.

메모리를 더 달라고 요청하는 때에 실행.

JVM은 메모리를 부여받고 열심히 프로그램들을 실행하다가 메모리가 부족해지는 순간이 오면 OS에게 추가로 메모리를 더 요청하게 된다. 이 시점에서 가비지 컬렉터(Garbage Collector)가 실행된다.

Reachability

Java의 GC는 가비지 객체를 판별하기 위해 reachability 라는 개념을 사용한다. 어떤 객체에 유효한 참조가 있으면 ‘reachable’, 없으면 ‘unreachable’로 구별하고 ‘unreachable’객체를 가비지로 간주한다.

reachability를 제어할 수 있다면 코드를 통해 Java GC에 일부 관여할 수 있다.

Reference



on Java, 자바, Gc, 가비지컬렉터