자바는 개발자가 메모리를 명시적으로 해지 하지 않고 GC가 더 이상 사용하지 않는 객체에 대해 메모리를 해지 하는 작업을 진행한다. GC에 대해 이해하기 위해서는 자바의 메모리 할당 방식에 대해 먼저 알필요가 있는데 ,
자바가 사용하는 메모리 영역은 크게 PC레지스터 , JVM 스택 , Heap , 메서드 영역, 런타임 상수 풀 , 네이티브 메서드 스택이 있다. (자세한건 여기 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5) 이 중 CG의 대상이 되는 영역은 Heap 영역인데 인스턴스 객체나 array가 쌓이는 메모리 영역이다.
이 Heap영역에 대해 JVM은 물리적 공간을 크게 두가지로 나누었다. Young 영역, Old 영역.
명칭대로 Young 영역에는 최근에 생성된 객체들이 할당 되고, Old영역에는 Young 영역에서 몇번의 GC이 실행 된 후 생존한 객체들이 옮겨 오는 영역이다.
Young 영역보다는 Old영역의 크기가 큰데, 이 때문에 Young 영역에서의 GC 작업은 minor GC라고 부르고 Old영역은 Major GC(Full GC)라고 부른다.
Young 영역 은 다시 Eden , Survivor 영역으로 나눠지는데, 이글을 작성하기 위해 참조한 naver D2의 글에 보면,
Eden 영역에 최초로 객체가 만들어지고, Survivor 영역을 통해서 Old 영역으로 오래 살아남은 객체가 이동한다는 사실은 꼭 기억하기 바란다.
라고 되어 있다. 꼭 기억하자.
GC의 알고리즘을 이해하고 상황에 따라 알맞는 알고리즘을 선택해야하는 이유는, JVM에서 GC가 일어날경우 GC를 실행하는 스레드를 제외하고 모든 스레드는 정지된다. 이 순간을 stop the world라고 부르며, 이 stop the world의 시간을 줄이는것이 GC 튜닝의 핵심이라고 이야기한다. CPU/메모리 등의 여러 조건을 보고 효과적인 알고리즘을 선택하여 stop the world를 줄이기 위해 GC에 대해 이해해야하는 것이다.
- Serial GC
-> 싱글 CPU의 경우 사용, 성능이 좋지 않음. 실제 운영서버에서 사용 X
-> 클라이언트 JIT컴파일러의 경우 Serial GC를 사용
->Old 영역에 대해서는 Mark-sweep-compact 컬렉션을 사용(살아있는 객체를 마크-> sweep->남은 객체를 앞으로 정리)
– - Parallel GC
-> Serial GC와 같은 알고리즘이지만, GC를 위한 스레드가 여러개
-> Old영역에 대해 Mark-sweep-compact 컬렉션을 사용한다는 점은 serial과 같음
– - Parallel Old GC(Parallel Compacting GC)
-> Old영역에 대한 컬렉션 알고리즘이 Parallet GC와 다름
– - Concurrent Mark & Sweep GC(이하 CMS)
-> 힙 메모리 영역이 클 경우 적합한 GC
-> Young영역에 대한 컬렉션은 Parallel GC와 같은 알고리즘을 사용하지만 Old영역에 대한 알고리즘이 다름
-> 재표시 단계와 생존한 객체를 왼쪽으로 몰아넣는(컴팩트) 단계가 없음
-> Parallel GC에서 사용되는 알고리즘에 비해 Stop-the-world 가 짧게 두번 발생한다는 점이 다름
– - G1(Garbage First) GC
-> 다른 4개의 컬렉터와 좀 다른형태, Young과 Old영역이 물리적으로 나눠져 있지않고 해당 영역의 객체들을 Region이라는 구역에 할당한다. 이 region이라는 구역이 Eden, Survivor, Old 같은 영역의 역활을 바꿔가며 수행하게 된다.
-> Old 영역의 GC알고리즘 경우, CMS CG와 비슷한데, 살아 있는 객체 에 대해 마지막에 복사단계를 통해 비어있는 구역으로 이동시키는점이 추가적으로 발생된다.
-> CG 성능이 가장 빠름(stop-the-world의 시간이 가장짧음)
참고 : http://d2.naver.com/helloworld/1329, 자바성능튜닝이야기(이상민 지음)