hip 영역은 객체들의 놀이터로서 객체 멤버 변수들은 객체와 함께 가비지 컬렉터라고 하는 힙 메모리 회수기에 의해 일생을 마친다고 했다.
그러면 Garbage Collection이 어떻게 동작하는지 알아보자
1. Garbage Collection이란?
Garbage Collection은 자바의 메모리 관리 방법으로 heap 영역에서 동적으로 할당했던 메모리 중 더이상 사용하지 않는 즉 필요없게 된 메모리 객체를 주기적으로 제거해 주는 것을 말한다.
C언어에서 malloc(), free() 함수를 사용해 보았다면 free() 함수와 유사한 역할을 한다. c언어에서는 메모리 해제를 개발자가 직접 해줘야 하지만 java에서는 Garbage Collection이 자동으로 메모리를 관리해 준다.
2. heap 영역의 구조
heap 영역은 처음 설계될 때 2가지를 전제로 설계되었다고 한다.
- 대부분의 객체는 금방 참조되지 않는 상태가 된다.
- 오래된 객체에서 새로운 객체로의 참조는 적게 발생한다.
hip은 크게 Young Generation 과 Old Generation 두개의 영역으로 나뉜다. 그리고 Young Generation에서 또 Eden 영역 Survivor 0, Suvivor 1 세개의 영역으로 나뉘게 된다.
2-1 Young 영역
새롭게 생성된 객체가 할당되는 영역이다. 대부분의 객체가 금방 Unreachable 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다가 사라진다. Young 영역에 대한 가비지 컬렉션을 Minor GC 라고 부른다.
2-2 Old 영역
Young 역역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역이다. Young 영역보다 크게 할당되면 영역의 크기가 큰 만큼 가비지 컬렉션은 적게 발생한다. Old 영역에 대한 가비지 컬렉션을 Major GC라고 부른다.
3. Garbage Collection 대상
Garbage Collection은 heap 메모리에서 더이상 사용하지 않는 객체 더이상 필요없게 된 메모리를 지워버린다고 했다. 그러면 더이상 필요없게 된 객체를 어떻게 판단하는 것일까?
3-1 도달능력(Reachability)
Garbage Collection이 대상을 판단하기 위해 도달 능력(Reachability)이라는 개념을 이용한다.
객체가 참조되고 있다면 Reachable 로 구분되고 객체가 더이상 참조되고 있지 않다면 Unreachable 로 구분해 수거해 버린다.
3-2 Root Space
그러면 객체가 참조되고 있는지 확인하기위해 도달 능력이라는 개념을 활용한다면 어디서 부터 객채를 참조 하는 것인가? 그것은 루트로 부터 객체에 접근이 가능한지가 해제의 기준이 된다.
JNM에서 Root Space 는 Heap 메모리 영역을 참조하는 static 영역 static 변수, stack, native method stack이 되게 된다.
4. Garbage Collection 동작 방식
4-1 Minor GC
Minor GC 는 Young 영역에 대한 가비지 컬렉션이다. Young 영역은 Old 영역에 비해 상대적으로 작기 때문에 메모리 상의 객체를 찾아 제거하는데 시간이 적게 걸린다.
처음 생성된 객체는 Young 영역의 일부인 Eden 영역에 위치한다. 객체가 계속 생성되어 Eden 영역이 꽉차게 되고 Minor GC가 실행 되면 Mark 동작을 통해 reachable 객체를 탐색한다.
Eden 영역에서 살아남은 객체는 1개의 Survivor 영역으로 이동 하고 Eden영역에서 사용되지 않는 객체는 메모리를 해제(sweep)한다.
또 다시 객체가 가득 차게 된다면 Minor GC 가 발생하고 Mark 하고 sweep 한다.
이때 살아남은 객체들은 비어있는 Surivor 로 이동하게 된다.
살아남은 모든 객체들은 살아남을때 마다 age 값이 1씩 증가하게 되는데 age 값이 임계값에 다다르면 Old 영역으로 이동 여부를 결정한다.
4-2 Major GC
Young 영역에서 살아남은 객체들의 age가 임계영역에 도달하면 Old영역으로 이동(promotion) 하게 된다. Old 영역의 공간도 부족하게 되면 가비지컬렉션이 발생하는데 그것을 Major GC라고 부른다.
Old 영역에 할당된 메모리가 가득 차게 되면 Old 영역에 있는 모든 객체들을 검사하게 되는데 Old 영역은 Young 영역보다 상대적으로 큰 공간을 가지고 있어 상당히 많은 시간이 걸리게 된다. 여기서 Stop-the-world 문제가 발생하게 된다.
Stop-the-world란 Major GC 가 발생하면 쓰레드가 멈추고 Mark and Sweep 작업을 해야해서 Cpu에 부하를 주는 현상을 말한다.