Garbage Collection
Garbage Collection(이하 GC)은 JVM에서 메모리 관리를 위한 중요한 기능입니다. GC는 메모리의 Heap 영역에 할당된 객체 중에서 더 이상 참조되지 않는 객체를 제거하여 메모리를 확보하는 작업을 말합니다. 이 과정에서 불필요한 객체가 메모리에서 제거됨으로써, 프로그램의 메모리 사용 효율을 높이고 OutOfMemoryError 같은 문제를 예방할 수 있습니다.
Stop The World
GC가 동작하는 동안 GC 관련 Thread를 제외한 나머지 Thread는 모두 멈추게 되는데, 이를 Stop-The-World라고 합니다. 이 현상은 GC가 수행될 때마다 발생하기 때문에, GC가 자주 실행되거나 실행 시간이 길어지면 성능 저하로 이어질 수 있습니다. 이러한 이유로 GC 최적화는 애플리케이션 개발에 매우 중요한 요소 중 하나 입니다.
GC의 종류
GC는 크게 두 가지로 구분됩니다:
- Minor GC: Young Generation 영역에서 발생
- Major GC (Full GC): Old Generation에서 발생
이를 이해하려면 먼저 JVM의 Heap 영역 구조를 알아야 합니다.
Heap 구조

Young Generation
Young Generation은 새로 생성된 객체들이 저장되는 영역입니다. Young Generation의 GC는 Minor GC라고 불리며, 이 영역은 다시 Eden과 Survivor1, Survivor2 영역으로 나뉩니다.
- Eden 영역: 객체가 Heap에 최초로 할당되는 장소입니다. Eden 영역이 가득 차면, 참조가 있는 객체는 Survivor 영역으로 이동하고, 참조가 없는 객체는 삭제됩니다. 이 과정이 바로 Minor GC입니다.
- Survivor 영역: Eden에서 살아남은 객체가 저장됩니다. Minor GC가 반복되며 살아남은 객체는 Old Generation으로 이동하게 됩니다.
Old Generation
Old Generation은 Young Generation에서 살아남은 오래된 객체들이 저장되는 영역입니다. 애플리케이션에서 일정 횟수 이상 참조된 객체가 Old Generation으로 이동합니다. 이곳에서 발생하는 GC는 **Major GC(또는 Full GC)**라고 불리며, 이 과정은 Minor GC보다 오래 걸립니다. Old Generation으로의 이동을 줄이면 Full GC 빈도를 줄여 성능을 개선할 수 있습니다.
Permanent Generation
Permanent Generation은 클래스의 메타 데이터나 메소드의 메타 데이터, Static 변수, 상수와 같은 JVM의 실행에 필요한 데이터가 저장됩니다. JDK 8 이후에는 Metaspace로 변경되었습니다.
GC의 성능 최적화
1. Young Generation, Old Generation 크기 조정
Young Generation 크기를 적절히 조정하면, 객체가 Old Generation으로 이동하기 전에 Minor GC로 삭제될 확률을 높일 수 있습니다. Old Generation 크기를 키우면 Full GC 횟수가 감소하지만 실행 시간이 길어지고 크기를 줄이면 실행시간이 감소하지만 횟수가 증가하고 Out Of Memory Exception이 발생할 수 있기 때문에 실행중인 어플리케이션에 적절한 크기를 설정하는 것이 중요합니다.
2. Object 생성 최소화
Object 생성을 최소화하면 Old Generation으로의 객체 이동이 줄어들기 때문에 Major GC 발생 빈도를 줄여 애플리케이션의 Stop-The-World 현상을 줄일 수 있습니다. 예를 들면 문자열 데이터가 가변적인 상황에서는 String 객체보다는 StringBuilder나 StringBuffer를 사용하면 객체 생성을 줄일 수 있습니다.
3. GC 알고리즘 선택
JVM은 다양한 GC 알고리즘을 제공하며, 애플리케이션 특성에 맞는 GC 알고리즘을 선택하는 것이 중요합니다. 대표적으로 Serial GC, Parallel GC, CMS GC, G1 GC 등이 있습니다.
'Java' 카테고리의 다른 글
[Java] String, StringBuilder, StringBuffer (0) | 2024.11.05 |
---|---|
[Java] Java 예외 처리: 체크 예외와 언체크 예외, 예외와 에러의 차이 (2) | 2024.11.05 |
[Java] 스트림(Stream)이란 (0) | 2024.11.04 |
[Java] 제네릭이란? (0) | 2024.11.03 |
[Java] final 필드, 메소드, 클래스 (0) | 2024.10.30 |