가비지 컬렉션
🗑️ 가비지 컬렉션 (Garbage Collection)
가비지 컬렉션(GC)은 프로그램이 동적으로 할당했던 메모리 영역 중에서, 더 이상 사용되지 않는 객체(쓰레기, Garbage)를 찾아내어 자동으로 해제하는 기능입니다. 이를 통해 개발자가 직접 메모리를 관리해야 하는 번거로움을 줄여주고, 메모리 누수(Memory Leak)와 같은 오류를 방지합니다.
C언어처럼 개발자가 직접 `free()`를 호출하여 메모리를 해제하는 방식과 대조됩니다.
🤔 GC는 어떻게 쓰레기를 찾을까?
GC의 핵심은 '도달 가능성(Reachability)'이라는 개념입니다. 어떤 객체가 유효한 참조를 가지고 있으면 '도달 가능'하다고 하고, 그렇지 않으면 '도달 불가능'(쓰레기)하다고 판단합니다.
1. GC Root에서 시작하여, 참조 관계를 따라 모든 객체를 탐색합니다. (GC Root는 스택 변수, 전역 변수 등 항상 참조 가능한 시작점입니다.) 2. 탐색 과정에서 만나는 모든 객체에 '마크(Mark)'를 남깁니다. 3. 마킹이 끝나면, 마크되지 않은 모든 객체들을 쓰레기로 간주하고 메모리에서 제거합니다. (이 과정을 '스윕(Sweep)'이라고 합니다.)
이러한 방식을 Mark-and-Sweep 알고리즘이라고 부릅니다.
🛑 Stop-the-World
GC가 실행될 때는, GC를 제외한 모든 애플리케이션 스레드가 일시적으로 중단됩니다. 이를 'Stop-the-World'라고 부릅니다. GC가 메모리 상태를 정확하게 파악하고 정리하려면, 애플리케이션이 메모리 상태를 바꾸지 못하도록 멈춰야 하기 때문입니다.
이 'Stop-the-World' 시간이 길어지면 애플리케이션의 성능 저하 및 응답 지연의 원인이 될 수 있어, GC 튜닝의 핵심 목표는 이 시간을 줄이는 것입니다.
💡 개발자 핵심 Point
- 가비지 컬렉션은 Java, C#, Python, Go 등 현대적인 프로그래밍 언어 대부분이 채택한 자동 메모리 관리 기법입니다.
- GC 덕분에 개발자는 메모리 관리에 대한 부담을 덜고 비즈니스 로직에 집중할 수 있습니다.
- 하지만 GC가 만능은 아닙니다. 불필요한 객체 참조를 계속 유지하면 메모리 누수가 발생할 수 있으며, GC 동작 방식에 대한 이해 없이 코드를 작성하면 심각한 성능 문제를 야기할 수 있습니다.
- 특히 대규모 실시간 서비스에서는 GC 튜닝(GC 종류 변경, 옵션 조절 등)이 매우 중요한 최적화 작업 중 하나입니다.