GC란?
가바지 컬렉션은 자바의 메모리 관리 방법 중 하나로 JVM의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객체를 모아 주기적으로 제거하는 프로세스 입니다.
C/C++ 언어에서는 GC가 없어 직접 메모리 할당과 해제를 해주어야 했지만, Java에서는 GC가 대신 메모리 관리를 해주기 때문에, 개발자 입장에서 메모리 누수 문제에 대해 관리하지 않고, 개발에만 집중할 수 있습니다.
STW(Stop-The-World)
GC는 메모리가 언제 해제되는지 정확하게 알 수 없어 제어하기 힘들며, GC가 동작하는 동안에도 다른 동작을 멈추기 때문에 오버헤드가 발생되는 문제점이 있습니다.
이를 Stop-The-World 라 합니다.
GC를 수행하기 위해 JVM이 프로그램 실행을 멈추는 현상을 의미합니다.
GC가 작동하는 동안 GC 관련 스레드를 제외한 모든 스레드는 멈추게 됩니다.
이를 방지하기 위해 효율적인 GC를 최적화해야 하는데 이를 GC 튜닝이라 하며, 개발자의 작업이 됩니다.
STW가 발생하는 이유
애플리케이션의 스레드가 멈추어야 현재 메모리 상에서 살아있는 객체를 정확히 식별할 수 있기 떄문입니다.
만약 멈추지 않는다면, 애플리케이션의 동작에 따라 변화하는 객체들의 상태를 반영하지 못할 수도 있기 때문입니다.
따라서 STW를 발생시켜 객체들의 상태를 완전히 반영하는 것 입니다.
GC의 종류
Minor GC
Young 영역에서의 GC 작업입니다.
주로 객체의 수명을 짧은 것들을 회수하는 작업을 진행하며, STW 현상이 발생합니다.
Minor GC는 매우 빠르게 실행되어 중단 시간이 짧습니다.
Major GC
Old 영역에서의 GC 작업으로 입니다.
오래된 객체들이 유지되는 영역 입니다.
Major GC는 더 큰 규모의 GC 작업으로, STW 현상이 더 길게 발생할 수 있습니다.
Full GC
Young + Old 영역 모두에서 GC 작업을 수행하는 경우 입니다.
Major GC의 한 종류로 모든 영역에서 GC 작업을 동시에 수행하므로 중단 시간이 길어지고, 발생 빈도는 적습니다.
Mark-Sweep 알고리즘
Mark 단계
이 단계에서 Reachable(참조되는) 객체들을 마킹하여 어떤 객체들이 여전히 참조되고 있는지 식별합니다.
마킹은 보통 루트에서 진행되고, 어플리케이션 시작 지점에서 참조되는 객체들로 구성됩니다.
루트에서 시작하여 참조를 따라가며 객체들을 마킹합니다.
Sweep 단계
마크 단계 이후 힙 영역을 스캔하며 마킹되지 않는 객체를 찾습니다.
마킹되지 않은 객체를 찾아내고, 객체들의 메모리를 회수합니다.
Serial GC
가장 간단한 GC이며, 싱글 스레드로 동작합니다.
GC가 실행될 때 모든 애플리케이션 스레드를 정지시킵니다.
멀티스레드 프로그램에서는 좋지 안은 방법입니다.
Parallel GC
Java8의 디폴트 GC입니다.
SerialGC와 관리 힙 공간을 위해 멀티 스레드를 사용해서 STW 시간을 최소화 합니다.
Minor GC는 멀티스레드, Major GC는 싱글 스레드로 작업합니다.
Parallel Old GC는 MinorGC, MajorGC 둘다 멀티 스레드로 작업합니다.
CMS GC
Concurrent Mark Sweep의 약자로 Heap 메모리가 클때 사용합니다.
다수의 스레드를 사용해, GC 동작 시 최소한의 pause 타임을 가지도록 설계됬으며, 애플리케이션이 실행되는 동안 GC와 프로세스의 리소스를 공유할 수 있습니다.
- Initial Mark싱글 스레드로 수행되고, STW 시간을 최소화합니다.
- Old 영역에 있는 객체 중 GC 루트에서 직접 참조하는 객체, Young 영역의 객체에서 참조하는 객체를 빠르게 마킹합니다.
- Concurrent Mark애플리케이션 작업과 동시에 수행해서 STW가 발생하지 않습니다.
- 1단계에서 marking된 객체가 참조하는 객체를 대상으로 살아 있는 객체를 추가 확인합니다.
- Remark
- 이전 단계에서 식별한 객체를 다시 추적해, 추가되거나 참조가 끊긴 객체를 확정합니다.
CMS GC는 GC 대상을파악하는 과정이 복잡한 여러 단계로 수행되기 때문에 GC 대비 CPU 사용량이 높고, 메모리파편화 문제가 있습니다.
G1 GC
CMS GC를 개선하기 위해 나왔으며, CMS GC에 비해 효율적으로 동작합니다.
- Mark : 다른 CG와 달리 힙을 동일한 크기의 영역(region)으로 분할한다. 각 영역은 가상 메모리에서 연속된 공간으로 위치한다. 힙 전체에 대해 liveness를 결정하기 위해 동시에 모든 힙 영역에 marking을 수행합니다.
- Sweep : 마킹이 끝나면 가장 많이 차 있는 영역을 찾아내서 해당 영역부터 GC를 수행한다.
물리적 Generation 구분을 없애고 전체 Heap을 1~32MB 단위의 Region으로 변경하였습니다.
가용 메모리를 영역별로 동적으로 할당하여 가바지 컬렉션을 수행하며, 응답 시간을 높였습니다.
'Back-end' 카테고리의 다른 글
자바 static (0) | 2023.08.13 |
---|---|
접근 지정자 (0) | 2023.08.13 |
JVM (0) | 2023.08.11 |
2023.08.08 TIL (0) | 2023.08.09 |
2023.08.07 TIL (0) | 2023.08.07 |