Java - Garbage Collection
Garbage Collection 이란 ?
프로그래머는 힙을 사용할 수 있는 만큼 자유롭게 사용하고,
더 이상 사용되지 않는 인스턴스(쓰레기객체)들은 가비지 컬렉션을 담당하는 프로레스가 자동으로
메모리에서 제거하도록 하는 것이 가비지 컬렉션의 기본이다.
프로그램을 실행하다가 메모리가 부족해져 메모리가 더 필요해지는 시점에 실행됩니다.
GC와 Reachability
Java GC는 객체가 가비지인지 판별하기 위해서 reachability라는 개념을 사용합니다.
어떤 객체에 유효한 참조가 있으면 'reachable'로, 없으면 'unreachable'로 구별하고, unreachable 객체를 가비지로 간주해 GC를 수행하게됩니다.
한 객체는 여러 다른 객체를 참조하고, 참조된 다른 객체들도 마찬가지로 또 다른 객체들을 참조할 수 있으므로 객체들은 참조 사슬을 이룹니다.이런 상황에서 유효한 참조 여부를 파악하려면 항상 유효한 최초의 참조가 있어야 하는데 이를 객체 참조의 root set이라고 한다.
가비지 컬렉션 영역
가비지 컬렉션은 세가지 영역으로 나눌 수 있습니다.
- Yung
- Eden
- Survivor 0
- Survivor 1
- Old
- Perm
- 생성된 객체들의 정보의 주소값이 저장된 공간.
- class loader에 의해 load되는 Class , Method등에 대한 Meta정보가 저장되는 영역
- JVM에 의해 사용된다. 직접 사용할 일이 없습니다.
- Refelction을 사용하여 동적으로 클래스가 로딩되는 경우에 사용
- Java 7이후부터 MetaSpace 로 변경되었습니다.
가비지 컬렉션 종류
GC는 크게 두개의 타입으로 나뉩니다.
- Major GC
- Old영역이나 , Perm영역에서 발생하는 GC
- full GC라고도함
- Minor GC
- Yung영역에서 발생하는 GC
위의 두가지 GC가 어떻게 상호작용하느냐에 따라서 , GC방식에 차이가 발생하며, 성능에도 영향을 줍니다.
가비지 컬렉션 프로세스
- 새로운 오브젝트는 Eden 영역에 할당된다. 두개의 Survivor Space 는 비워진 상태로 시작합니다.
- Eden 영역이 가득차면, MinorGC 가 발생합니다.
- MinorGC 가 발생하면, Reachable 오브젝트들은 S0 으로 옮겨진다. Unreachable 오브젝트들은 Eden 영역이 클리어 될때 함께 메모리에서 사라집니다.
- 다음 MinorGC 가 발생할때, Eden 영역에는 3번과 같은 과정이 발생합니다.. Unreachable 오브젝트들은 지워지고, Reachable 오브젝트들은 Survivor Space 로 이동합니다. 기존에 S0 에 있었던 Reachable 오브젝트들은 S1 으로 옮겨지는데, 이때, age 값이 증가되어 옮겨집니다. 살아남은 모든 오브젝트들이 S1 으로 모두 옮겨지면, S0 와 Eden 은 클리어 된다. Survivor Space 에서 Survivor Space 로의 이동은 이동할때마다 age 값이 증가합니다.
- 다음 MinorGC 가 발생하면, 4번 과정이 반복되는데, S1 이 가득차 있었으므로 S1 에서 살아남은 오브젝트들은 S0 로 옮겨지면서 Eden 과 S1 은 클리어 됩니다. 이때에도, age 값이 증가되어 옮겨진다. Survivor Space 에서 Survivor Space 로의 이동은 이동할때마다 age 값이 증가합니다.
- Young Generation 에서 계속해서 살아남으며 age 값이 증가하는 오브젝트들은 age 값이 특정값 이상이 되면 Old Generation 으로 옮겨지는데 이 단계를 Promotion 이라고 합니다.
- MinorGC 가 계속해서 반복되면, Promotion 작업도 꾸준히 발생하게 됩니다.
- Promotion 작업이 계속해서 반복되면서 Old Generation 이 가득차게 되면 MajorGC 가 발생하게 됩니다.
가비지 컬렉션 방식
- Serial GC(-XX:+UseSerialGC)
- Serial GC는 적은 메모리와 CPU코어 개수가 적을 때 적합한 방식입니다.
- old 영역에서 mark-sweep-compact 알고리즘사용
- 살아있는객체를 마크, sweep , 남은객체를 앞으로 정리
- Parallel GC(-XX:+UseParallelGC)
- Serial GC와 기본적인 알고리즘은 같지만, 여러개의 Thread가 나누어 처리하는 방식입니다.
- Old영역에 대해서 mark-sweep-compact 알고리즘을 사용한다는 점은 Serial과 같음
- Parallel Old GC(-XX:+UseParallelOldGC)
- ParallelGC에 비해 Old영역에 대한 알고리즘만 다르고 여기서는
- mark-summary-compaction 알고리즘을 사용
- summary단계에서는 앞서 GC를 수행한 영역에 대해서 별도로 살아있는 객체를 식별
- ParallelGC에 비해 Old영역에 대한 알고리즘만 다르고 여기서는
- Current Mark Sweep(CMS) GC(-XX:UseConcMarkSweepGC)
- 초기 Initial Mark 단계에서는 클래스 로더에서 가장 가까운 객체중 살아있는 객레를 찾는 것으로만 끝낸다
- 따라서 멈추는시간이 아주짧다
- 그리고 Concurrent Mark단계에서는 살아있다고 확인한 객체에서 참조하고 있는 객체들을 따라가면서 확인한다.
- 여기서 특징은 다른스레드가 실행중인 상태에서 동시에 진행된다는 것이다.
- 그다음 Remark단계에서는 Current Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다.
- 마지막으로 ConCurrent Sweep 단계에서는 쓰레기를 정리하는 작업을 실행한다.
- 이작업도 다른 스레드가 실행되고 있는 상황에서 진행된다.
- 장점
- 장점으로는 stop -the -world시간이 매우 짧아, 모든 어플리케이션 응답속도가 중요할때 CMS GC를 사용한다.
- 단점
- 다른 방식보다 CPU를 많이 사용하며,
- Compaction단계가 기본적으로 제공되지 않는다.
- 조각난 메모리가 많아, Compaction을 실행하면 다른 GC보다 stop-the-world 시간이 길 기 때문에
- Compaction이 얼마나 자주, 오래동안 수행되는지 확인해야한다.
- 초기 Initial Mark 단계에서는 클래스 로더에서 가장 가까운 객체중 살아있는 객레를 찾는 것으로만 끝낸다
5. G1 GC
- G1(Garbage First)
- G1 GC를 이해하려면 지금까지의 Young 영역과 Old 영역에 대해서는 잊는 것이 좋다.
- G1 GC는 바둑판 각 영역에 객체를 할당하고 CG를 실행한다.
- 해당영역이 꽉차면 다른 영역에서 객체를 할당하고 GC를 실행한다.
- 즉, Yung의 가지 영역에서 Old영역으로 이동하는 단계가 사라졌다고 보면된다.
- 장점
- 위에서 말했던 어떤 GC보다 빠르다
- JDK 7 에서 정식으로 포함하여 제공된다.
***Mark-sweep-compact 알고리즘
-
Old 영역으로 이동된 객체들 중 살아 있는 개체를 식별합니다. (Mark)
-
Old 영역의 객체들을 훑는 작업을 수행하여 쓰레기 객체를 식별합니다. (Sweep)
-
필요 없는 객체들을 지우고 살아 있는 객체들을 한 곳으로 모은다 (Compact)
GC 튜닝하기
http://d2.naver.com/helloworld/37111
'JAVA' 카테고리의 다른 글
boilerplate (2) | 2019.09.15 |
---|---|
Java - Atomic변수 (0) | 2019.09.02 |
Java - JVM (0) | 2019.09.02 |
Java - 메모리관리 ( 스택& 힙) [펌] (0) | 2019.09.01 |
Primitive vs Reference (0) | 2019.09.01 |
댓글