GC란?
Java Application은 JVM(Java Viirtual Machine) 위에서 구동됩니다. JVM에서는 Java Application이 사용하는 메모리를 관리하고 있는데 이 JVM의 기능중 더 이상 사용하지 않는 객체를 청소하여 공간을 확보하는 GC라는 작업이 있습니다.
GC란 Garbage Collection(쓰레기 객체 정리, 이하 GC)의 약자입니다. Java Runtime시 Heap 영역에 저장되는 객체들은 따로 정리하지 않으면 계속헤서 쌓이게되어 OutOfMemmory Exception이 발생할 수 있습니다. 이를 방지하기 위하여 JVM에서는 주기적으로 사용하지 않는 객체를 수집하여 정리하는 GC를 진행합니다.
GC 전 후의 메모리
JVM의 메모리 영역
GC 작업을 진행하는 Garbage Collector(가비지 콜렉터)는 GC를 위해 다음 역할을 합니다.
1. 메모리 할당
2. 사용중인 메모리를 인식
3. 사용하지 않는 메모리를 인식
위 세가지 작업을 통해 앞으로 메모리를 얼마나 사용할 수 있는지 파악하고 GC를 언제 진행할지 지정할 수 있습니다.
JVM의 메모리 영역은 다음과 같습니다.
Eden영역부터 Servior영역까지를 Young 영역이라고 부릅니다.
크게 Young, Old, Perm 영역으로 나누어 지는데 JDK 8버전 부터는 이 영역이 사라졌습니다.
객체 GC과정
객체가 생성되어 메모리에 올라간 후 사용하지 않을 때 GC되기까지의 과정입니다.
1. 객체가 생성되어 Eden 영역에 올라간다.
처음 생성된 객체는 Eden 영역에 할당됩니다. 이후 Eden영역이 꽉 찬다면 할당이 해제되지 않은 객체를 Servior 영역으로 이동시킵니다.
2. Eden 영역이 꽉 차면 Servior영역으로 넘어간다. 단 Servior 영역중 하나는 반드시 비어있어야 한다.
Servior 영역에 있는 객체는 올라가있는 Servior 영역이 꽉 찰 때 다시 GC 심사를 받습니다. 할당이 되어있고 아직 사용중이라는 판단이 들면 다른 Servior 영역으로 이동합니다.
단 여기서 Servior 영역을 거치지 않고 바로 Old 영역으로 이동하는 경우가 있습니다. 바로 객체의 크기가 Servior 영역의 크기보다 큰 경우입니다.
2-1. 객체의 크기가 Servior영역의 크기보다 큰 경우 Old 영역으로 이동한다.
3. 이 과정에서 오랫동안 살아남은 객체는 Old 영역으로 이동한다.
Old 영역에 들어간 객체는 풀 GC, 메이저GC가 발생하지 않는한 GC되지 않습니다.
GC의 종류
GC는 크게 메이저GC와 마이너GC로 나눌 수 있습니다.
메이저 GC | Old, Perm 영역에서 발생하는 GC |
마이너 GC | Young 영역에서 발생하는 GC |
풀 GC | 메모리 전체를 대상으로 하는 GC |
각 GC의 종류에 따라 성능에 크게 영향을 줍니다. 이 GC를 진행하는 방법에는 5가지 방식이 있습니다.
GC의 방식
1. Serial Collector
하나의 CPU로 Young영역과 Old영역을 연속적으로 처리합니다.
컬렉션이 수행될 때 애플리케이션이 정지됩니다.
Serial Collector은 다음 흐름으로 진행됩니다.
살아있는 객체는 Eden영역에 올라간다 -> Eden영역이 꽉차면 To Servivor영역으로 '살아있는 객체'를 이동시킨다 -> To Servivor영역이 꽉 찰경우 Eden, FromServivor영역에 남은 객체를 Old영역으로 이동시킨다
이후 Old영역에서는 쓰지 않는 객체를 표시해서 한 곳으로 모으고 삭제하는 'Mark serrp compact'알고리즘을 사용합니다. 해당 알고리즘은 다음 흐름으로 진행됩니다.
살아있는 객체를 찾아 표시한다 -> Old 영역을 스캔하여 쓰레기 객체를 표시한다 -> 쓰레기 객체를 지우고 살아있는 객체를 모은다
2. Parallel Collector
Parallel Collector의 목표는 다른 CPU가 GC의 진행시간 동안 대기 상태로 남아 있는 것을 최소화 하는 것입니다.
Serial Collector의 Young 영역에서 진행하는 컬렉션을 병력 방식으로 처리하여 GC의 부하를 줄이고 성능을 향상시킬 수 있습니다.
3. Parallel Compacting Collector
Parallel Collector에서 Old영역 컬렉션 알고리즘을 변경한 컬렉터입니다. Old영역에 대한 알고리즘은 다음 흐름을 따릅니다.
살아있는 객체를 표시한다 -> 이전 GC에서 살아있는 객체의 위치를 조사한다 -> 컴펙션을 수행한다
4. Concurrent Mark-Sweep(CMS)
CMS 콜렉터는 힙 메모리의 크기가 클 때 적합합니다. Young 영역에 대한 처리 방법은 Parallel Collector의 Young 영역의 GC 알고리즘과 동일합니다. Old 영역의 GC는 다음 흐름을 따릅니다.
짧은 대기 시간으로 살아있는 객체를 찾는다 -> 서버 수행시 살아있는 객체에 표시를 한다 -> 표시 도중에 변경된 객체에 대해 다시 표시한다 -> 표시된 쓰레기를 정리한다
CMS 방식에서는 컴팩션을 하지 않습니다. 따라서 메모리를 몰아놓지 않으므로 다른 옵션을 사용해서 메모리를 모아주는 작업이 필요합니다.
5.Garbage First Collector(G1)
G1 콜렉터는 Young영역과 Old영역으로 나누는 방식을 사용하지 않는 특이한 컬렉터입니다. G1 컬켁터는 바둑판 모양으로 구성되어있으며 약 2000개의 구역을 사용합니다.
이 바둑판 모양의 구역에서 일부를 선정하여 Young 영역으로 지정한 후 해당 구역에 데이터가 꽉 차면 GC를 진행합니다. GC 후 살아있는 객체만 Servivor영역으로 이동합니다.
출처 : 해당 포스팅은 '자바 성능 튜닝 이야기'를 보며 정리한 글입니다.
'Java > 기초' 카테고리의 다른 글
[Java] Java는 Call by reference가 없다 (25) | 2020.03.24 |
---|---|
[Java] jConsole로 원격에서 실행중인 JVM 모니터링하기 (0) | 2020.02.14 |
[Java] 이클립스 설치방법 - JDK 1.7 설치, Eclipse Luna 설치 (0) | 2019.08.23 |
[Java] String .split(".")결과가 공백이 나올 때 해결방법 (1) | 2019.08.21 |
[java] 스레드(Thread)[4] - 스레드의 상태(state) 제어 (0) | 2019.07.27 |
댓글