Garbage Collection
C/C++ 프로그래밍에서는 메모리 누수(Memory Leak)를 막기 위해 개발자가 직접 명시적으로 메모리 관리를 해야한다. 그러나 자바에서는 JVM이 구성된 JRE(Java Runtime Environment)가 제공되며, 그 구성요소 중 하나인 Garbage Collection(GC)이 자동으로 사용하지 않는 객체를 메모리에서 제거해준다.
Stop-the-World 현상
- GC가 사용하지 않는 객체를 메모리에서 해제하는 작업을 수행할 때, JVM이 애플리케이션 실행을 일시적으로 멈추는 것
- stop-the-world 현상이 발생하는 시간을 최소화 하는 것이 성능 개선을 위한 주요 과제 중 하나이다.
GC를 수행하지 않거나 GC를 해도 더 이상 사용 가능한 메모리 영역이 없는데 메모리를 할당하려는 경우 OutOfMemoryError가 발생하여 WAS가 다운 될 수 있다.
GC 대상이 되는 경우
- 객체가 NULL인 경우
- 블록 실행 종료 후, 블록 안에서 생성된 객체
- 부모 객체가 NULL인 경우, 포함하는 자식 객체
GC의 메모리 해제 과정
1. Marking
GC 프로세스는 주기적으로 메모리를 스캔하며, 어떤 객체가 참조되고 있는지 확인한다.
- 모든 객체를 스캔하며 참조되고 있는 객체와 그렇지 않은 객체를 구분
- 참조되고 있는 객체는 메모리에서 "파란색"으로 표시되고, 참조되지 않는 객체는 "주황색"으로 표시
- 모든 객체를 스캔하기 때문에 시간이 많이 소요될 수 있다.
2. Normal Deletion
Marking 단계에서 참조되지 않는 객체가 표시되면, GC는 이러한 객체들을 실제로 삭제하고 해당 메모리를 반환한다.
- 참조되지 않는 객체들을 메모리에서 제거하고, 그 메모리를 다른 용도로 재사용할 수 있도록 한다.
- 메모리 할당자(Memory Allocator)는 반환된 메모리 블록의 참조 위치를 추적하고, 새로운 객체가 생성될 때 해당 메모리를 할당한다.
3. Compacting
참조되지 않는 객체를 제거한 후, 남아있는 참조되는 객체들을 모아 메모리를 압축(Compact)한다. 이렇게 함으로써 아래와 같은 이점을 얻을 수 있다.
- 메모리 공간을 연속적으로 만들어 새로운 객체가 메모리에 할당될 때 더 효율적으로 진행된다.
- 압축된 메모리 영역은 더 높은 캐시 히트(Cache Hit) 확률을 가지며 성능을 향상시킨다.
- 물리적으로 메모리를 정리함으로써 가비지 컬렉션 이후의 메모리 구조가 더 최적화 된다.
Generational Garbage Collection
Generational GC는 JVM에서 사용되는 GC 알고리즘 중 하나로, 메모리 관리를 위해 Young 영역, Old 영역과 같이 여러 영역으로 메모리를 나누어 관리하는 방법이다. 이 방식은 Weak Generational Hypothesis에 기반하고 있으며, 자주 생성되고 빠르게 불필요해지는 객체와 오래된 객체를 분리하여 관리한다.
1. Young 영역
- 새로 생성된 대부분의 객체가 Young 영역에 위치한다.
- 대다수의 객체는 금방 접근 불가능한 상태가 되며, 매우 많은 객체가 Young 영역에 생성되었다가 사라진다.
- Young 영역에서 객체가 사라질 때, 이를 "Minor GC"라고 한다.
- Minor GC는 Young 영역에 한정된 GC 작업을 수행하며, 상대적으로 빠르게 완료된다.
- Young 영역은 Eden 영역과 두 개의 Survivor 영역(S0, S1)으로 나뉘며, 새로운 객체는 Eden 영역에 할당된다.
- Eden에서의 객체 생존 여부에 따라 Survivor 영역으로 이동하며, 점점 오래된 객체들이 Old 영역으로 이동한다.
2. Old 영역
- Young 영역에서 접근 불가능 상태로 되지 않아 살아남은 객체가 Old 영역으로 복사된다.
- Old 영역은 Young 영역보다 크게 할당되며, 크기가 큰 만큼 GC는 적게 발생한다.
- Old 영역에서 객체가 사라질 때, 이를 "Major GC" 또는 "Full GC"라고 한다.
- Major GC는 Young 영역와 Old 영역 모두를 대상으로 GC 작업을 수행한다.
3. Permanent 영역
- 클래스와 메서드의 메타데이터를 포함하는 곳이다.
- JDK 8부터는 Permanent 영역 대신 Metaspace가 도입되었다.
- Metaspace는 Native Heap 영역에 위치하며, 동적으로 크기를 조정할 수 있다.
Generational Garbage Collection 동작 과정
- 새로운 객체가 들어오면 Eden 영역에 할당
- Eden 영역이 가득차면 Minor GC가 시작되고 Young 영역 내에서 살아있는 객체들을 식별
- Eden 영역과 현재 사용중인 Survivor 영역(S0 or S1)에 있는 객체들 중에서 살아남은 객체를 검사하고, 참조되지 않는 객체를 삭제
- 살아남은 객체들은 다른 Survivor 영역으로 이동하고, 이 과정에서 나이(age) 정보를 증가시킨다. 나이가 특정 임계값에 도달한 객체는 Old 영역으로 이동할 수 있다.
- Old 영역의 메모리가 부족해지면 Major GC 발생
[참고] https://d2.naver.com/helloworld/1329
https://gyoogle.dev/blog/computer-language/Java/Garbage%20Collection.html
'Languages > Java' 카테고리의 다른 글
[Java] Stream API (0) | 2023.09.14 |
---|---|
[Java] Error & Exception (0) | 2023.09.07 |
[Java] JVM (Java Virtual Machine) (0) | 2023.09.06 |
[Java] 고유 락 (Intrinsic Lock) (0) | 2023.08.31 |
[Java] 스레드 (Thread) (0) | 2023.08.31 |