[JAVA] 가비지 컬렉션(Garbage Colletion)
JVM(Java Virtual Machine)이란?
운영체제의 메모리 영역에 접근하여 메모리를 관리하는 프로그램
메모리 관리, Garbage Collection 수행
Garbage Collector란?
동적으로 할당한 메모리 영역 중 사용하지 않는 영역을 탐지하여 해제하는 기능
Stack과 Heap
- stack
- 정적으로 할당한 메모리 영역
- 원시 타입의 데이터가 값과 함께 할당, Heap영역에 생성된 Object 타입의 데이터 참조 값 할당
- Heap
- 동적으로 할당한 메모리 영역
- 모든 오브젝트 타입의 데이터가 할당, Heap영역의 Object를 가리키는 참조 변수가 Stack에 할당
public class Main {
public static void main(String[] args) {
int num1 = 10;
int num2 = 5;
int sum = num1 + num2;
String name = "java";
System.out.println(sum);
System.out.println(name);
}
}
위와 같은 코드를 실행하게 되면 Stack에 순차적으로 num1, num2, sum이 생기고 String은 객체이므로 Heap에 생기고 객체를 참조하는 변수가 stack에 저장된다.
이후 main메소드 실행이 끝나면 Stack영역에 있는 데이터는 날라가고 Heap영역에 있는 객체 타입의 데이터만 남게되는데 이러한 객체를 Unreachable Object라고 하며 가비지 콜렉터의 대상이 된다.
Garbage Collector 과정
1. Garbage collector가 Stack의 모든 변수를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
2. Reachable Object가 참조하고 있는 객체도 찾아서 마킹한다.
3. 마킹되지 않은 객체를 Heap에서 제거한다.
* Mark and Sweep 참조되는 객체를 마킹(Mark)하고 그 외에 것들 다 삭제(Sweep)한다
Garbage Collection은 언제 일어날까?
메모리 관리 과정
1. GC(Minor)
New(Young) Generation에서 일어나는 GC
- 새로 생성된 객체는 Eden영역에 위치
- GC 발생하여 Mark and Sweep 과정을 통해 Eden 영역의 Unreachable 객체는 메모리 해제되고 Reachable 객체는 Survival0로 옮겨짐
- 위 과정이 반복되어 Survival0 영역이 다 차면 GC 발생, 그 후 살아남은 객체는 Survival1영역으로 이동하게 되고 이 과정에서 이동한 객체는 Age값이 증가됨
- Eden영역에서 GC발생시 survival 두 개의 영역 중 이미 객체가 차 있는 영역으로 쌓인다 -> survial0 survival1 둘 중 하나는 항상 비어있다.
- survival1영역이 다 차면 다시 또 survival0로 이동하고 age값 증가
2. Promotion
위 과정 반복하면서 age값이 특정 값을 넘어서면 Old Generation 영역으로 이동
3. GC(Major)
Old Generation영역도 모두 다 찼을 때 발생하는 GC
GC의 종류
Stop-The-World란?
GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것이다.
stop-the-world가 발생하면 GC를 실행하는 스레드를 제외한 나머지 스레드는 모두 작업을 멈춘다.
GC 작업을 완료한 이후에 중단한 작업을 다시 시작한다.
- Serial GC
- GC를 처리하는 스레드가 1개이다.
- CPU 코어가 1개만 있을 때 사용하는 방식
- Mark-Compact collection 알고리즘 사용
- mark and sweep 과정에 compact과정이 추가된 것
- 데이터가 해제되고 나서 군데군데 조각난 공간을 없애서 메모리 파편화를 방지
- Parallel GC
- GC를 처리하는 스레드가 여러개
- Serial GC보다 빠르게 객체를 처리할 수 있다.
- 메모리가 충분하고 코어의 개수가 많을 때 사용하면 좋다.
- Concurrent Mark Sweep GC (CMP GC)
- stop-the-world 시간을 줄여서 속도가 중요한 애플리케이션 등에 사용
- 다른 GC방식보다 메모리와 CPU를 더 많이 사용한다.
- Compaction 단계가 제공되지 않는다.
- G1 GC
- 각 영역을 Region 영역으로 나눈다.
- 바둑판의 각 영역에 객체를 할당하고 GC를 실행한다.
- 그러다가 해당 영역이 꽉 차면 다른 빈 영역에 객체를 할당하고 GC를 실행한다.
- GC가 일어날 때 전체 영역(Eden, Survival, Old generation)을 탐색하지 않는다.
- 지금까지 설명한 Young의 세가지 영역(Eden, Survival 2가지 영역)에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식이라고 이해하면 된다.
- STW 시간이 짧다
- Compaction을 사용한다.