Inor
[JAVA] GC(Garbage Collection : 종류와 과정) 본문
Garbage Collection
C와 C++을 공부 해봤던 사람이라면 객체나 메모리를 할당 할때 특정 명령어(malloc, new)를 사용하는 것을 알고 있을 것 입니다. 그리고 메모리를 해제하는 명령어(free, delete) 사실을 알고 있을 것 입니다. 그러나 자바에서는 개발자가 객체를 생성하는 것은 가능하지만 메모리에 할당된 객체를 삭제하는 것은 허락하지 않습니다. 자바가 추구하는 것들 중 하나가 메모리 관리의 편리성이기 때문이라고 알고 있습니다.
Stop-The-World
자바는 멀티 스레드 환경이고 Garbage Collection 또한 특정 스레드에서 동작 하게 됩니다. Garbage Collection이 실행 될 때 애플리케이션의 모든 스레드는 정지하고 Garbage Collection 스레드만 동작하게 됩니다. 이것을 Stop-The-World라고 합니다. 개발자가 임의로 Garbage Collection을 호출 할 수 있지만 이런 행동(System.gc())은 애플리케이션의 성능을 떨어뜨리는 행동이 될 수 있습니다. Garbage Collection 튜닝의 기본은 Stop-The-World의 시간을 줄이는 것이라고 합니다.
Young Generation & Old Generation
Heap 영역은 Garbage Collection의 대상이 되는 영역들 중 하나 입니다. Heap 영역에는 크게 Young Generation과 Old Generation으로 영역이 나뉘어져 있습니다. '대부분의 객체는 금방 접근 불가 상태(unreachable)가 된다.'와 '오래된 객체가 젊은 객체를 참조하는 경우는 드물게 존재한다.'는 두 가지 가설의 장점을 최대한 살리기 위해서 만들어진 영역들 입니다.
- Young Generation : 새로 생성된 객체들은 이 영역에 속하게 되고 그 객체들 중 대부분은 금방 접근 불가 상태가 되기 때문에 Garbage Collection의 대상이 됩니다. 이 영역에서 객체가 사라질 때 Minor GC가 호출이 됩니다.
- Old Generation : Young 영역에 있던 객체들이 참조를 잃지 않고 오래 살아 남으면 Old 영역으로 이동이 됩니다. 대부분 Young 영역보다 크게 할당이 되고 크기가 크기 때문에 자주 GC가 호출이 되지 않습니다. 이때 호출되는 GC를 Major GC라고 부릅니다.
- Serial GC
- Parallel GC
- Old Parallel GC
- Concurrent Mark & Sweep GC(CMS GC)
CMS GC는 아래와 같은 형식으로 진행이 됩니다. 각 단계를 살펴보면 처음 Initial Mark 단계에서 클래스로더와 가장 가까운 객체 중에 살아있는 객체만을 확인 합니다. 이 단계에서는 Stop-The-World가 발생하며 모든 것을 확인하는 것이 아니기 때문에 다른 스레드들이 멈추는 시간이 적습니다. Concurrent Mark 단계에서는 Initial Mark 단계에서 찾은 객체들이 참조하고 있는 객체들을 찾아 가면서 살아 있는 객체들을 확인 합니다. 이 단계에서는 Stop-The-World가 발생하지 않습니다. 그리고 Remark 단계에서는 Concurrent 단계를 진행 하면서 중간에 새로 참조 되거나 참조가 끊긴 객체들을 확인 합니다. 이 단계에서는 Stop-The-World가 발생 합니다. 그리고 Concurrent Sweep 단계에서는 이제 참조가 되지 않고 있는 객체들에대한 정리를 합니다. 이 단계에서는 다른 스레드들을 멈추지 않고 진행 합니다.
다른 GC 방식들 보다 Stop-The-World 시간이 적다는 장점을 갖고 있지만 다른 방식보다 메모리와 CPU를 많이 사용한다는 단점이 있고 Compaction 단계가 없다는 특징이 있습니다. 조각난 메모리에대한 Compaction을 해야 할 경우에 다른 GC보다 Stop-The-World 시간이 길어질 수 있습니다. 따라서 얼마나 자주 Compaction을 해야하는지 확인 후 사용해야 합니다.
- G1 GC
Heap 영역은 동일한 연속된 동일한 크기의 공간으로 나뉘어져 있습니다. 각 영역의 크기는 정해진 것이 아니기 때문에 메모리 영역의 사용에대한 유연성을 제공 할 수 있습니다. GC가 시작되면 G1은 CMS와 비슷한 방식으로 동작 합니다. Heap 메모리에 객체가 살아 있는지 동시적이고 전역적인 마킹을 수행 합니다. 검사가 끝나면 어떤 영역의 메모리가 가장 많이 비어있는지 확인 할 수 있고 그 공간부터 메모리 회수를 시작 합니다. 그렇게 때문에 Garbage First(G1)이라는 이름을 갖고 있는 것 입니다. 그리고 G1에 의해서 교체를 해야 되는 공간은 배출(evacuation)에 의해서 GC를 시작 합니다. 하나 이상의 공간에서 객체를 복사해 다른 공간으로 이동 시킵니다. 이 과정에서 메모리 공간의 최적화가 수행 됩니다. 배출은 멀티 프로세스에 의해서 병렬처리가 되기 때문에 Stop-The-World 시간이 줄어들 수 있습니다.
참고
- http://d2.naver.com/helloworld/1329
- http://sarc.io/index.php/java/255-g1-garbage-collector
- http://appchemist.net/tag/garbage-collector/
'Computer Engineering > Java' 카테고리의 다른 글
[JAVA] Hiding(Static Method Overriding) (0) | 2017.07.17 |
---|---|
[JAVA] Overloading과 Overriding (0) | 2017.07.17 |
[JAVA] ClassLoader(JAVA : 클래스 로더의 구조) (0) | 2017.07.12 |
[JAVA] JVM(Java Virtual Machine : 자바 가상 머신의 구조) (0) | 2017.07.11 |
[JAVA] OOP(Object-Oriented Programing : 객체지향프로그래밍) (0) | 2017.07.06 |