2012년 1월 29일 일요일

Java Garbage Collection에 대해서


1. GC란?

GC는 JVM에서 쓰지 않는 메모리를 자동으로 회수하는 녀석을 말한다.

2. GC의 동작 방법

JVM 메모리 영역 3가지

YOUNG/OLD/PERM

Perm은 Method Area라고도 한다. 객체나 억류된 문자열 정보를 저장하는 곳이다.
여기서 GC가 발생해도 Major GC 횟수에 포함된다.
Perm에서의 GC (http://tuning-java.com/455) String intern한 정보에 대해서 FullGC가 발생한다.



GC 알고리즘

(1) Minor GC

Young은 Eden/Survior로 나뉘게 된다. 그런데 Survivor구역이 두개다 그래서 총 3개의 영역을 Young의 영역으로 보개된다.

YOUNG - EDEN 
            -  SURVIVE1,2
OLD

EDEN : 처음 객체가 생성될시에 상주한다.

Minor Gc가 발생시 아래와 같이 위치를 이동한다.

[MINOR GC 1차 발생시]

EDEN에서 ALIVE하면 SURVIVE1으로 이동한다.
EDEN CLEAR

[MINOR GC 2차 발생시]

EDEN에서 [alive] - > Survivor 2
Survivor  1  [alive] - > Survivor 2
Eden    Clear
Survivor 2 Clear

[MINOR GC 3차 발생시]

객체 생성시간이 오래지나면 Eden과 survivor영역에 있는 오래된 객체들을 Old 영역으로 이동

이런방식의 GC알고리즘을 Copy & Scavenge라고 한다. 이방법은 속도가 빠르며 작은 크기의 메모를 Collection하는데 매우 효과적이다. Minor Gc는 자주 일어나기 때문에 GC에 소요되는 시간이 짧은 알고리즘에 적합.

(2) Full GC(Major GC)

Old영역에서의 GC를 Full GC라고 부르며, Full Gc에 사용되는 알고리즘은 Mark & Compact라는 알고리즘을 사용한다. 

Mark는 전체 객체들의 레퍼런스를 쭉 따라가면서 레퍼런스가 연결되지 않은 객체들을 Mark한다. 이 작업이 끝나면 사용되지 않은 객체들이 Mark되고 Mark된 객체를 삭제한다.

Compact는 mark된 객체로 생기는 부분을 unmark된 사용하는 객체로 매꾸어 버리는 방법이다. 덮어쓰기?!

Full Gc는 속도가 매우 느리다. Full GC가 일어나면 순간적으로 Java app이 STW하기 때문에 FullGc가 일어나는 정도와 Full GC에 소요되는 시간은 App의 성능과 안정성에 큰영향을 준다.


3. GC가 중요한 이유

Minor Gc는 보통 0.5초로 빠르지만 Full GC의 경우 느리다. 5~10초 GC로 인해서 만약 app이 멈췄다가 풀리면 WAS의 경우 요청이 큐에 저장됬다가 한번에 엄청나게 봇물 터지듯이 받게 된다면 DDOS공격같은 효과로 부하가 발생해서 뻗어 버릴수가 있다.



4. 다양한 Old영역에 대한 GC 알고리즘

JDK7기준으로 5가지의 GC방식이 있다.

- Serial GC (쓰지 말자 싱글쓰레드 방식의 GC)
- Parallel GC
- Parallel Old GC(Parallel Compaction GC)
- Concurrent Mark & Sweep GC (이하 CMS)
- G1(Gargage First) GC (아직 시기상조 JDK7이라서 불안)

(1) Serial GC ( -XX:+UseSerialGC)

young 영역은 앞서 설명한 방식을 사용한다. 
Old영역에서 mark - sweep - compact방식을 사용한다.

- 순서     

     1. Old영역에서 살아있는 객체를 mark한다. 
     2. heap의 앞부분부터 확인하여 살아 있는것만 남긴다.(이게 sweep) 
     3. 각 객체들이 연속되어 쌓이도록 힙의 가장 앞부분부터 채워서 객체가 
         존재하는 부분과 객체가 없는 부분으로 나눈다.(Compaction)

Serial은 싱글 cpu 고려 한 알고리즘이라 코어갯수가 적을때 적합하다.(쓰지말자)


(2) Parallel GC( -XX:+UseParallelGC)

기본 알고리즘은 비슷하다. 
다만 싱글쓰레드로 처리하던 Serial GC에 비해서 멀티쓰레드로 처리하기 때문에 Serial보다 빠르다.
Parallel GC는 메모리가 충분하고 코어 갯수가 많을수록 유리하다.
Parallel GC는 Throughtput GC 라고도 불린다.

(3) Parallel Old GC(-XX:+UseParallelOldGC)

Parallel Old Gc는 jdk5 update 6부터 제공하는 Gc 이다. 앞서 Parallel Gc와 비교시 Old영역 Gc알고리즘이 틀리다.

이 방식은 Mark - Summary - Compaction 단계를 거친다.

Summary단계는 앞서 GC를 수행한 영역에 대해서 별도로 살아 있는 객체를 식별한다는 점에서 Mark-Sweep-Compaction 알고리즘의 Sweep단계와 다르며, 
약간더 복잡한 단계를 거친다.

(4) CMS GC(-XX:+UseConcMarkSweepGC)



1. initial Mark단계에서는 클래스 로더에서 가장 가까운 객체중 살아 있는 객체만 찾는것으로 끝낸다. 
따라서 멈추는 시간이 매우 짧다. 
2. Concurrent Mark 단계에서는 방금 살아 있다고 확인한 객체에서 참조하고 있는 객체들만 따라가면서 확인한다. 
이단계의 특징은 다른 쓰레드가 실행중인 상태에서 동시에 진행된다는 것이다.
3. Remark 단계에서는 Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다. 
4.Concurrent Sweep 단계에서는 쓰레기를 정리하는 작업을 실행한다. 
이 작업도 다른 쓰레드가 실행되는 상황에서 진행된다.

장점 . 

이러하기 때문에 표를 봐도 알수 있듯이 Stop the world 가 짧다.
모든 애플리케이션의 응답속도가 매우 중요할때 Cms GC 를 사용하며 Low latency GC 라고도 불린다.

단점 . 

다른 GC보다 cpu와 메모리를 많이 쓴다.(자원먹는 괴물)
Compaction단계가 기본적으로 제공되지 않는다. (기본적으로는 없다.)

그리고 조각 난 메모리가 많아 Compaction작업을 실행하면 다른  GC 방식의 stw 보다 시간이 더 길기 때문에 Compaction작업이 얼마나 자주, 오랫동안 수행되는지 확인(테스트)해야한다.

(5) G1 GC

이 녀석은 young ,old 영역 구분이 없다.
바둑판으로 각 영역에 객체를 할당하고 GC 를 실행한다. 그러다가 해당영역이 꽉차면 다른 영역에 객체를 할당하고 GC를 실행한다.
즉, young의 세영역(eden,survivor1,2)영역에서 데이터가 old로 이동하던 단계가 없다.
G1 GC 는 장기적으로 말도 많고 탈도 많은 CMS GC를 대체하기 위해서 만들어 졌다.

G1 GC 의 장점은 성능이다. 
위의 녀석들중 최고다 하지만 나온지 얼마안되서 불안하다 시기상조이니 좀 시간이 흐른후 적용하도록하자.


- 출처 : 

http://helloworld.naver.com/helloworld/1329
http://jikime.tistory.com/313

두글을 제가 보기좋게 짬뽕했습니다.

댓글 없음:

댓글 쓰기