가비지 컬렉션은 JVM이 더 이상 사용하지 않는 객체(Garbage)를 자동으로 메모리에서 제거해주는 기능이다.
개발자가 일일이 free()처럼 메모리를 해제할 필요 없이, JVM이 알아서 메모리를 관리해주므로 안정성과 생산성이 높아진다.
자바에서는 new 키워드로 객체를 계속 생성하지만, 사용이 끝난 객체를 명시적으로 제거하지 않는다.
이 때문에 사용하지 않는 객체가 계속 메모리를 차지하면 메모리 누수가 발생할 수 있다.
이 문제를 해결하기 위해 JVM이 직접 참조되지 않는 객체를 찾아서 메모리에서 제거하게 된다.
가비지 컬렉션은 대표적으로 Mark and Sweep 방식으로 작동한다.
1️⃣ Mark 단계에서는 참조되고 있는 객체들을 찾아 표시한다.
2️⃣ Sweep 단계에서는 표시되지 않은 객체들을 메모리에서 제거한다.
이 과정을 통해 사용 중인 객체와 사용하지 않는 객체를 구분하고, 필요 없는 객체를 정리한다.
GC가 실행될 때는 GC를 제외한 모든 스레드의 작업이 중단된다.
이 현상을 Stop The World라고 하며, GC가 오래 걸릴수록 전체 애플리케이션이 멈춰 있는 시간이 늘어난다.
이로 인해 사용자 경험에 영향을 줄 수 있기 때문에 GC의 성능과 방식이 매우 중요하다.
| 구분 | 대상 영역 | 특징 |
|---|---|---|
| Minor GC | Young 영역 (Eden + Survivor) | 새로 생성된 객체를 대상으로 자주 발생하며, 작고 빠르다. |
| Major GC (Full GC) | Old 영역 | 오래 살아남은 객체를 대상으로 발생하며, 느리고 무겁다. Stop The World 시간이 길다. |
Heap
├── Young (Eden + Survivor)
│ └─ Minor GC 발생
├── Old
│ └─ Major GC (Full GC) 발생
Minor GC는 Young 영역에서 발생하는 GC이다.
새로 생성된 객체는 Eden 영역에 저장되며, 대부분의 객체는 짧은 생명주기를 가지므로 이 영역에서 금방 제거된다.
살아남은 객체는 Survivor 영역으로 이동하며, 여러 번 GC를 통과하면 Old 영역으로 이동하게 된다.
Minor GC는 속도가 빠르고 자주 발생하기 때문에 일반적인 앱 성능에 큰 영향을 주지 않는다.
Major GC는 Old 영역에서 발생하는 GC이다.
여러 번 Minor GC를 통과해 살아남은 객체들이 모인 Old 영역은 구조가 크고 복잡하다.
Major GC는 Old 영역 전체를 스캔하고 참조되지 않는 객체를 제거하며, 압축(Compaction) 작업까지 수행한다.
이 때문에 실행 시간이 길고 Stop The World 시간도 길어져 시스템에 영향을 줄 수 있다.
| 이유 | 설명 |
|---|---|
| Old 영역이 큼 | 살아남은 객체들이 많아 탐색해야 할 범위가 넓다. |
| 압축 작업 존재 | 객체를 제거한 뒤, 남은 객체를 모아 빈 공간을 정리해야 한다. |
| Stop The World 발생 | GC가 실행되는 동안 모든 스레드가 멈추기 때문에 시간 지연이 크다. |
| 구조가 복잡함 | Minor GC보다 작업량이 많고 복잡한 구조를 가진다. |