가비지 컬렉션(Garbage Collection, GC)
garbage collection이란
메모리 관리 기법 중 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요 없게 된 영역을 해제하는 기능
garbage collection 사용
장점
- 유효하지 않은 포인터 접근(이미 해제된 메모리에 대해 접근)하는 오류를 막을 수 있다.
- 이중 해제(이미 해제된 메모리를 또다시 해제하는 버그)를 막을 수 있다.
- 메모리 누수(더 이상 필요하지 않은 메모리가 해제되지 않고 남아있는 버그)를 막을 수 있다.
단점
- 어떤 메모리를 해제할지 결정하는 데 비용이 든다.
- garbage collection이 일어나는 타이밍이나 점유 시간을 미리 예측하기 어렵다. 때문에 프로그램이 예측 불가능하게 일시적으로 정지할 수 있다.(실시간 시스템에 적합 X)
- 할당된 메모리가 해제되는 시점을 알 수 없다.
Auto Garbage Collection
C와 같은 프로그래밍 언어에서 메모리 할당 및 할당 해제는 수동 프로세스.
Java에서 메모리 할당 해제 프로세스는 가비지 수집기에서 자동으로 처리.
기본 프로세스
1 단계 - 마킹
garbage collection은 사용 중인 메모리와 사용하지 않는 메모리를 식별합니다.
위와 같은 그림을 얻기 위해(참조 된 객체 - 파란, 참조 안된 객체 - 주황) 모든 물체를 스캔한다.

2단계 - 일반 삭제
참조되지 않은 객체를 제거하여 참조 된 객체와 사용 가능한 공간에 대한 포인터를 남긴다.
메모리 할당자(memory allocator)는 새로운 객체가 할당될 수 있는 여유 공간 블록에 대한 참조를 보유

2_a 단계 - 압축을 사용한 삭제
참조되지 않은 객체를 삭제하는 것 외에도 성능 향상을 위해 나머지 참조 된 객체를 압축할 수도 있다.
참조된 객체를 함께 이동하면 새 메모리 할당이 훨씬 쉽고 빠르다.

JVM Generation
객체 할당 동작에서 얻은 정보는 JVM의 성능을 향상하는 데 사용될 수 있다.
힙 파트는 Young Generation, Old 또는 Tenured Generation 및 Permanent Generation.

Young Generation
- 새로운 모든 객체들이 할당되고 나이를 먹어간다.
- 이 영역에서 발생되는 garbage collection을 minor garbage collection이라고 부른다.
- Young Generation이 가득 차면 minor garbage collection이 발생된다. 높은 개체 사망률을 가정한다면 minor garbage collection을 최적화할 수 있다.
- Young generation은 죽은 객체들로 가득차게 되면 빠르게 수집될 수 있다.
- 몇몇 생존한 객체들은 나이를 먹어가고 결국엔 old generation으로 옮겨진다.
Stop the World Event
- 모든 minor garbage collections들은 "Stop the World" 이벤트이다. 즉 작업이 완료 될 때까지 모든 응용 프로그램 스레드가 중지된다.
Old Generation
- 오랫동안 살아남은 객체들이 저장되는 곳
- 일반적으로 young generation 객체에 대한 입계 값이 설정되고 해당 연령이 충족되면 개체가 이전 세대로 이동된다.
- Major garbage collecition 또한 Stop the World 이벤트이다. major collection은 종종 모든 살아있는 객체들을 포함하기 때문에 매우 느리다. 그래서 Responsive application(반응형 응용프로그램)들은 major garbage collections를 최소화해야 한다.
Permanent Generation
- 애플리케이션에 사용되는 종류 및 방법을 설명하는 JVM에 필요한 메타 데이터를 포함한다.
세대 별 Garbage Collection 프로세스
- JVM에서 객체 할당 및 에이징 프로세스 안내
1. 먼저 어떤 새로운 객체가 eden space로 할당된다. 두 survivor space 모두 비어있는 상태이다.

2. eden space이 가득 차면 minor garbage collection이 시작된다.

3. 참조된 객체들은 첫 번째 survivor space로 이동한다. 참조되지 않은 객체들은 eden space가 정리될 때 삭제된다.

4. 다음 일어나는 minor garbage collection에서는 이전과 같은 일이 일어난다.
참조되지 않은 객체들은 삭제되고 참조된 객체들은 survivor space로 이동한다. 하지만 이 경우 두 번째 survivor space(S1)으로 이동한다.
또한 마지막 minor garbage collection 때 첫 번째 survivor space(S0)에 있는 객체들은 나이가 올라가고 S1로 이동한다.
살아남은 모든 객체가 S1로 이동하면 S0과 eden은 모두 지워진다.(이제 survivor space에 나이 먹은 객체를 가지고 있게 되었다.)

5. 다음 minor garbage collection에서는 동일한 프로세스가 반복된다. 그러나 이번에는 survivor space가 바뀐다.

6. 객체의 나이가 특정 임계 값에 도달하게 되면 young generation에서 old generation으로 이동하게 된다.

7. minor garbage collection이 계속 발생하고 객체들은 계속해서 이전 세대 공간으로 승격하게 된다.

8. 따라서 young generation에서 거의 전체 프로세스를 다뤄지고 결국엔 공간을 정리하고 압축하는 old generation에서 main garbage collection이 수행될 것이다.

Java Garbage Collectors
종류:
The serial GC(직렬 GC)
Java SE 5 및 6에서 Client Style Machines의 기본값
The Serial GC를 이용하면 minor garbage collector와 major garbage collector가 모두 단일 가상 CPU를 사용하여 직렬로 수행
mark-compact 수집 방법을 사용
mark-compact: 오래된 메모리를 힙의 시작 부분으로 이동시켜 새로운 메모리 할당이 힙의 끝에 a single continuous chunk of memory로 만들어진다. 이러한 메모리 압축으로 인해 새로운 메모리 청크를 힙에 더 빨리 할당 할 수 있다.
The Parallel GC(병렬 GC)
The Parallel GC는 multiple threads를 사용하여 young generation garbage collection을 수행.
기본적으로 N CPU가 있는 호스트에서 The Parallel GC는 콜렉션의 N garbage collector thread를 사용.
command-line options로 garbage collector thread 수를 컨트롤 할 수 있다.
Reference
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
www.oracle.com