목차
GC란?
Java Application은 JVM(Java Viirtual Machine) 위에서 구동됩니다. JVM에서는 Java Application이 사용하는 메모리를 관리하고 있는데 이 JVM의 기능중 더 이상 사용하지 않는 객체를 청소하여 공간을 확보하는 GC라는 작업이 있습니다.
GC란 Garbage Collection(쓰레기 객체 정리, 이하 GC)의 약자입니다. Java Runtime시 Heap 영역에 저장되는 객체들은 따로 정리하지 않으면 계속헤서 쌓이게되어 OutOfMemmory Exception이 발생할 수 있습니다. 이를 방지하기 위하여 JVM에서는 주기적으로 사용하지 않는 객체를 수집하여 정리하는 GC를 진행합니다.
JAVA에서 GC의 도입의 전제 가설 (weak generational hypothesis)
- 대부분의 객체는 금방 접근 불가능 상태 (unreachable)가 된다.
- 오래된 객체에서 젋은 객체로의 참조는 아주 적게 존재한다.
아래와 같이 객체를 생성하고 해당 객체의 어떤 동작을 10,000번 수행하는 반복문에서 마지막 한번을 제외 한 9,999번의 객체들은 생성 후 바로 접근 불가능 상태가 된다. 이를 unreachable 상태라고 하며, GC가 발생하지 않으면 10,000개의 객체 현재 참조 되지 않지만 메모리를 점유 하고 있다고 볼 수 있다.
for (int i = 0; i < 10000; i++) {
SampleObj obj = new SampleObj();
obj.doTest(i);
}
또 아래와 같이 객체를 생성하고 다른 메소드나 클래스에 해당 객체를 전달 후 에는 다시 참조 하지 않는 경우가 대 부분이다. 이를 오래된 객체에서 젊은 객체로의 참조는 아주 적게 발생 한다라고 말 할 수 있다.
SampleObj obj = new SampleObj();
obj.setValue(1);
doTest2(obj);
JVM의 메모리 영역
GC의 수행영역별 구분
Eden영역부터 Servior영역까지를 Young 영역이라고 부릅니다. 크게 Young, Old, Perm 영역으로 나누어 지는데 JDK 8버전 부터는 이 영역이 사라졌습니다.
GC는 수행되는 영역에 따라 두가지로 구분 할 수 있다.
GC가 수행되는 영역에 따라 Minor GC 와 Major GC(Full GC) 로 구분한다.
- Minor GC는 Eden과 Survivor1,2의 Young Generation 영역의 객체를 메모리에서 삭제한다.
- Major GC는 Minor GC과정에서 삭제 되지 않고, Old Generation영역으로 옮겨진 객체 중 미사용 된다고 판단되는 객체를 메모리에서 삭제한다.
SWT(Stop-The-World)
GC를 이해하고자 할 때 중요한 요소가 있다.
GC가 발생하고 이를 수행하는 과정에서 진행중인 쓰레드는 멈추고 GC를 수행하는 쓰레드만 동작하게 되는 데 이를 Stop-The-World 라 부른다. 이 Stop-the-world가 경우에 따라서는 시스템 장애로 이어 질 수 있기 때문에 GC와는 떼어 놓을 수 없다.
메모리 영역이 크게 설정 되어 있으면, GC가 발생하는 횟수를 줄일 수 있지만, GC 수행 시간은 증가 하기 때문에 최적화가 필요 할 수 밖에 없는 이유이다.
STW (Stop-The-World)
- GC가 발생하면 JVM은 어플리케이션을 멈추고, GC를 실행하는 쓰레드만 동작하게 되고 이를 Stop-The-World 라고 한다.
- STW가 발생하는 동안은 어플리케이션이 중지 되기 때문에 장애로 이어 질 수 있다.
GC 발생 시나리오
GC는 기본적으로 다음과 같은 시나리오로 동작한다.
객체가 생성되면 Eden 영역에 위치 하게 된다.
Eden영역이 가득차게 되면 Minor GC가 발생하여 참조가 없는 객체는 삭제되고, 참조 중인 객체는 Suvvivor 영역으로 이동한다.
Survivor영역이 가득차게 되면 Minor GC가 발생하고 참조가 없는 객체는 삭제되고, 참조 중인 객체는 다른 Survivor2영역으로 이동한다.
Survivor 영역에서의 GC과정을 반복 하며, 계속 참조 중인 객체는 OLD 영역으로 이동한다.
예외) Eden 영역에서 Survivor 영역으로 이동 할 때 객체가 남아있는 영역보다 큰 경우 OLD 영역으로 이동한다.
GC 수행 방식에 따른 종류와 변화
JVM 버전의 변화에 따라 여러가지 GC방식이 추가 되고 발전되어 왔다.
버전별로 지원하는 GC는 차이가 존재하며, 서비스 상황에 따라 필요한 GC방삭을 JVM옵션을 통한 설정으로 사용이 가능하다.
GC의 종류는 다음과 같다.
Serial Garbage Collector
- 주로 32비트 JVM에서 돌아가는 싱글쓰레드 어플리케이션에서 사용 (별도로 지정하지 않는 경우 기본 GC)
- Minor GC 뿐 아니라 Major GC인 경우도 올스탑(stop-the-world)하는 싱글쓰레드 방식.
Parallel Collector(=Throughput Collector)
- 64비트 JVM이나 멀티 CPU 유닉스 머신에서 기본 GC로 설정되어 있음.
- MinorGC와 MajorGC 모두 멀티쓰레드를 사용.
- MinorGC 뿐 아니라 Major GC인 경우도 올스탑(stop-the-world)
CMS Collector (Concurrent Mark-Sweep)
- Initial Mark 단계에서참조 상태인 객체를 짧은 시간에Marking 후,올스탑 없이 Concurrent Mark단계에서 참조상태 객체를 확인. Remark단계에서 변경되거나 추가된 객체를 확인. Concurrent Sweep 단계애서참조 되지 않는 객체를 정리.
- CPU리소스를 많이 사용, 메모리 파편화가 단점.
G1 Collector (Garbage First)
- 기존 Young, Old 영역의 개념과 다른 Heap에 Resion 개념을 도입함.
- 하나 이상의 Resion 에서 객체를 복사해 다른 Resion으로 이동 시키는 방식.
- CMS와 비슷한 방식으로 동작 시작. Heap에 전역적으로 Marking 하고, 가장 많은 공간이 있는 곳 부터 메모리 회수 진행. 이 부분 때문에 Garbage First 라는 이름이 붙었다.
- CMS Collector의 CPU리소스 및 메모리 파편화의 단점 해결.
참조
https://d2.naver.com/helloworld/1329
'Java' 카테고리의 다른 글
[Java] Java 8 에서의 변경사항 (0) | 2022.05.05 |
---|---|
추상클래스 vs 인터페이스 (0) | 2022.04.07 |
Java & Spring 버전 특징 정리 (0) | 2022.04.04 |
객체의 래퍼클래스(WrapperClass) (0) | 2021.09.16 |
IntelliJ IDEA 단축키 (0) | 2021.01.28 |