Garbage Collection이란?
Garbage Collection(GC)은 메모리 관리를 자동으로 처리해 주는 기능이다. Java, Kotlin 같은 언어에서는 개발자가 직접 메모리를 해제하지 않아도 되는데, 그 이유가 바로 이 GC 덕분이다. C 언어에서는 free()를 호출해 사용한 메모리를 수동으로 정리해야 하지만, Java는 JVM이 주기적으로 불필요한 객체를 감지하고 제거해 준다.
Java에서는 메모리 누수를 막기 위해 System.gc()로 GC를 강제 호출할 수도 있지만, 이 방법은 성능 문제를 일으킬 수 있으니 사용하지 않는 것이 좋다.
Minor GC와 Major GC
JVM의 힙 메모리는 크게 두 영역으로 나뉜다: Young Generation과 Old Generation이다. 이 두 영역은 객체의 생애 주기에 따라 나누어져 있다.
1) Young Generation
- 새로 생성된 객체들이 먼저 할당되는 공간이다.
- 대부분의 객체는 금방 사용되지 않게 되며, 주로 이 영역에서 생성되었다가 삭제된다.
- Young Generation에서 발생하는 가비지 수집을 Minor GC라고 한다.
2) Old Generation
- Young Generation에서 살아남은 오래된 객체들이 이동하는 공간이다.
- Young Generation보다 메모리 공간이 크며, 이곳에서 발생하는 GC는 Major GC라고 한다.
Young Generation에서는 자주 객체들이 생성되고 삭제되므로 Minor GC가 빈번하게 발생한다. 반면에 Old Generation은 좀 더 큰 객체들이나 오래 살아남은 객체들이 저장되므로, Major GC가 발생하는 빈도는 적다.
GC의 작동 원리
GC의 기본 작동 방식은 두 가지 단계로 이루어져 있다: Stop-The-World와 Mark and Sweep이다.
1) Stop-The-World
GC가 실행되면 JVM은 애플리케이션의 모든 작업을 일시 중지한다. GC가 완료될 때까지는 애플리케이션이 멈춘 상태로 있게 되는데, 이를 Stop-The-World라고 한다. 이 시간 동안 모든 실행 중인 스레드가 정지하기 때문에 성능에 영향을 미칠 수 있다.
2) Mark and Sweep
가비지 컬렉션은 Mark와 Sweep 두 단계를 거친다:
- Mark: 사용 중인 객체를 식별하고 표시한다.
- Sweep: Mark 되지 않은, 즉 사용되지 않는 객체를 메모리에서 제거한다.
이 과정은 메모리를 효율적으로 관리하기 위해 필수적이며, Stop-The-World 시간과 밀접한 관련이 있다. GC 튜닝을 통해 이 시간을 줄이는 것이 성능 최적화의 핵심이다.
Minor GC와 Major GC의 차이
- Eden: 새로 생성된 객체가 들어가는 곳.
- Survivor: Eden에서 살아남은 객체들이 이동.
Young Generation에서 발생하는 GC는 Minor GC라고 부르고, 이 과정에서 대부분의 객체가 메모리에서 제거된다. Eden 영역이 가득 차면 Minor GC가 발생하며, 살아남은 객체는 Survivor 영역으로 이동한다.
Old Generation에서는 Major GC가 발생하며, Minor GC보다 시간이 더 오래 걸린다. Old Generation은 크기가 크고 Young Generation에서 오래 생존한 객체들이 이동해오기 때문에, GC가 오래 걸리는 경우가 많다.
GC 성능 최적화
GC는 메모리를 자동으로 관리해 주기 때문에 편리하지만, Stop-The-World 시간이 길어지면 애플리케이션 성능에 영향을 줄 수 있다. 이를 해결하기 위해 GC 튜닝을 통해 메모리 사용 방식이나 GC 발생 빈도를 조정할 수 있다.
결론
이렇게 해서 Garbage Collection에 대한 개념을 정리해 보았다. GC는 자동으로 메모리를 관리해 주는 매우 유용한 기능이지만, 이를 잘 이해하고 관리하지 않으면 성능에 문제가 발생할 수 있다. GC의 작동 방식을 알고, 적절한 튜닝을 통해 최적화하는 것이 중요하다.
'JAVA' 카테고리의 다른 글
UncheckedException과 CheckedException (1) | 2024.09.13 |
---|---|
ArrayList는 어떻게 크기가 조절될까? (0) | 2024.09.11 |
Garbage Collection(GC) 더 자세히 살펴보기 (0) | 2024.09.09 |
Java final과 불변성 (0) | 2024.09.08 |
제네릭이란? (2) | 2024.09.04 |
인터페이스와 추상 클래스 (3) | 2024.09.03 |
나만의 메서드가 한 가지 기능만 하는지 확인하는 기준 (0) | 2023.10.07 |
좋은 코드를 위한 네이밍 기법들 (0) | 2023.09.27 |