-
[JAVA] GCstudy/java 2020. 8. 6. 00:43
GC란?
Java는 JVM ( Java Virtual Machine ) 위에서 구동이 된다.
JVM에서 애플리케이션이 사용하는 메모리를 관리하는 작업이 있는데 이를 GC라고 한다.
Garbage Collection의 약자로 런타임 시에 힙 영역에 저장되는 객체들을 주기적으로 확인하여 사용하지 않는 객체를 해제하여 정리하는 역할을 한다.
Stop-the-world
GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것을 말한다.
Full GC가 발생하면 JVM은 애플리케이션의 실행을 멈추고 GC를 실행하는 스레드만 동작한다.
웹 서버에서 Full GC가 발생하면 서비스는 중단될 것이고 서비스가 중단된 동안 각종 Time out이 발생할 것이며 미뤄진 작업들이 쌓여 또 다른 Full GC를 발생시키게 될 것이다.
Garbage Collector
메모리가 부족(memory leak)할 때 이런 가비지 ( 주소를 잃어버려 사용할 수 없는 메모리 + 앞으로 사용하지 않고 메모리를 가지고 있는 객체 ) 들을 메모리에서 해제시켜 다른 용도로 사용할 수 있도록 해주는 프로그램
역할
1. 힙의 객체 중 가비지를 찾아낸다.
2. 찾아낸 가비지를 처리해서 힙의 메모리를 회수한다.
JVM의 메모리 영역
Eden 영역부터 Survivor 영역까지는 Young 영역이라고 부른다.
GC의 종류
메이저 GC Old, Perm 영역에서 발생하는 GC 마이너 GC Young 영역에서 발생하는 GC 풀 GC 메모리 전체를 대상으로 하는 GC 방식
-
Serial GC
Young 영역의 처리 절차는 다음과 같다.
1. 새로 생성한 대부분의 객체는 Eden 영역에 위치한다.
2. Eden 영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다.
3. Eden 영역에서 GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 이동한다. 그리고 가득 찬 Survivor 영역은 아무 데이터도 없는 상태로 된다.
4. 이 과정을 반복하다가 계속 살아남은 객체는 Old 영역으로 이동한다.
Old 영역의 GC는 mark-sweep-compact라는 알고리즘을 사용한다.
1. Old 영역에 살아있는 객체(reachable)를 식별(mark)한다.
2. 힙의 앞 부분부터 확인하여 살아있는 것만 남긴다(sweep).
3. 각 객체들이 연속되게 쌓이도록 힙의 가장 앞부분부터 채워서 객체가 존재하는 부분과 없는 부분으로 나눈다(compaction).
적은 메모리와 CPU 코어 개수가 적을 때 적합한 방식이다.
-
Parallel GC ( Throuhtput GC )
기본적인 알고리즘은 Serial GC와 같지만 Serial GC는 GC를 처리하는 스레드가 하나인 반면 Parallel GC는 GC를 처리하는 스레드가 여러 개다.
그렇기 때문에 Serial GC보다 빠르게 객체를 처리할 수 있다.
Serial GC와는 반대로 메모리가 충분하고 코어 개수가 많을 때 유리한 방식이다.
-
Parallel Old GC
JDK 5 update 6부터 제공한 GC 방식이다.
Parallel GC와 비교하여 Old 영역의 GC 알고리즘만 다르다.
이 방식은 mark-summary-compaction 단계를 거치는데 여기서 summary 단계는 앞서 GC를 수행한 영역에 대해서 별도로 살아 있는 객체를 식별한다는 점에서 sweep 단계와 다르며 좀 더 복잡하다.
-
CMS GC
초기 Initial Mark 단계에서는 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾는다.
따라서 멈추는 시간이 매우 짧다.
Concurrent Mark 단계에서는 방금 살아있다고 확인한 객체에서 참조하고 있는 객체들을 따라가면서 확인한다.
이 단계는 다른 스레드가 실행 중인 상태에서 동시에 진행된다.
Remark 단계에서는 이전 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다.
마지막으로 Concurrent Sweep 단계에서는 가비지를 정리하는 작업을 실행한다.
이 작업 역시 다른 스레드가 실행되고 있는 상황에서 진행한다.
이러한 단계로 진행되기 때문에 stop-the-world 시간이 매우 짧다.
모든 애플리케이션의 응답 속도가 매우 중요할 때 CMS GC를 사용하며 Low Latency GC라고도 부른다.
시간이 짧다는 장점에 반해
1. 다른 GC 방식보다 메모리와 CPU를 더 많이 사용한다.
2. Compaction 단계가 기본적으로 제공되지 않는다.
라는 두 가지 단점이 있으므로 신중한 검토 후에 사용해야 한다.
-
G1 GC
다음 그림과 같이 G1 GC는 바둑판의 각 영역에 객체를 할당하고 GC를 실행한다.
그러다가 해당 영역이 꽉 차면 다른 영역에서 객체를 할당하고 GC를 실행한다.
G1 GC는 장기적으로 말이 많은 CMS GC를 대체하기 위해서 만들어졌다.
CMS GC는 힙 메모리를 하나의 큰 영역으로 보고 전체적으로 쓰고 지우기를 반복한다.
따라서 한번에 많은 양의 메모리를 지우게 되는 경우가 생기는데 G1 GC는 힙 메모리를 바둑판 형태로 여러 영역으로 나눈 뒤 각각의 영역에 대해서 GC를 진행하기 때문에 대규모 메모리 삭제 작업이 일어날 일이 적다.
G1 GC의 가장 큰 장점은 성능이다. 위의 4가지 방식들보다 빠르다
하지만 JDK 6에서는 G1 GC를 early access라고 부르며 그냥 시험 삼아 사용할 수 있도록 하고 JDK7에서 정식으로 포함하여 제공한다.
Reachability
- reachable : 어떤 객체에 유효한 참조가 있는 경우
- unreachable : 어떤 객체에 유요한 참조가 없는 경우 -> 가비지로 간주
메모리 누수 ( memory leak )
컴퓨터 프로그램이 필요하지 않은 메모리를 계속 점유하고 있는 상황
GC 튜닝
https://d2.naver.com/helloworld/37111
참고
https://d2.naver.com/helloworld/1329
'study > java' 카테고리의 다른 글
[JAVA] Exception (0) 2020.08.21 [JAVA] 제네릭 (0) 2020.08.08 [JAVA] Jar,War (0) 2020.08.04 [JAVA] static 키워드 (0) 2020.07.30 [JAVA] Try-with-resources (0) 2020.07.30 -