본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
JVM의 똑똑한 청소부, 가비지 컬렉션(GC) 파헤치기! 🧹✨

안녕하세요, 여러분! 🚀
지난 시간에는 JVM이 무엇이고, 왜 필요하며, 어떤 메모리 구조를 가지고 있는지 함께 살펴보았습니다. 특히 JVM의 "자동 메모리 관리" 기능, 즉 가비지 컬렉션(Garbage Collection, GC) 에 대해 살짝 언급했었죠? 🤖 바로 그 똑똑한 청소부가 어떻게 우리 대신 메모리를 관리해주는지, 오늘은 그 비밀을 파헤쳐 볼 시간입니다!
GC는 JVM 성능에 직접적인 영향을 미치기 때문에, 개발자라면 꼭 알아둬야 할 중요한 개념이랍니다. 자, 그럼 JVM의 숨은 일꾼, GC의 세계로 함께 떠나볼까요? 🧐
오늘 우리가 함께 탐험할 GC의 세계는 다음과 같습니다:
- GC란 무엇이고 왜 중요할까요? 🤔 (What is GC and Why is it Important?)
- GC는 어떻게 동작할까요? (과정 & 원리) ⚙️ (How does GC work? Process & Principles)
- 다양한 GC 친구들은 누가 있을까요? 👨👩👧👦 (Meet the various GC Algorithms)
자, 그럼 지금부터 GC의 매력에 흠뻑 빠져볼 준비, 되셨나요? 출발! ✨

GC란 무엇이고 왜 중요할까요? 🤔
JVM 메모리 구조, 특히 힙(Heap) 영역 기억나시죠? 프로그램에서 new 키워드로 생성되는 모든 객체와 배열이 저장되는 공간이었습니다. 만약 이 공간에 객체들이 계속 쌓이기만 하고 아무도 치우지 않는다면 어떻게 될까요? 당연히 메모리가 가득 차서 더 이상 새로운 객체를 만들 수 없는 OutOfMemoryError 가 발생하고 프로그램은 멈춰버릴 겁니다! 😱
GC(Garbage Collection)는 바로 이 힙 영역에서 더 이상 사용되지 않는 객체(쓰레기, Garbage)들을 찾아내고 제거하여 메모리를 효율적으로 사용할 수 있게 해주는 자동 메모리 관리 프로세스입니다.
GC 덕분에 개발자는 C/C++처럼 수동으로 메모리를 할당하고 해제하는 번거로움에서 벗어나 핵심 비즈니스 로직 개발에 더 집중할 수 있습니다. 메모리 누수(memory leak) 걱정도 덜 수 있죠! 😊
GC는 어떻게 동작할까요? (과정 & 원리) ⚙️

GC는 크게 보면 두 가지 질문에 답하는 방식으로 동작합니다: "어떤 객체가 쓰레기인가?" 그리고 "그 쓰레기를 어떻게 처리할 것인가?"
- 일반적인 GC 과정 (Young Generation & Old Generation)
- Young Generation (젊은 세대): 새롭게 생성된 객체들이 대부분 위치하는 영역입니다. 이 영역은 다시 Eden 영역과 두 개의 Survivor 영역(S0, S1)으로 나뉩니다.
- Old Generation (늙은 세대): Young Generation에서 오랫동안 살아남은 객체들이 이동하는 영역입니다.
- Minor GC: Young Generation에서 발생하는 GC입니다. 대부분의 객체는 금방 쓰레기가 되므로 Minor GC는 자주 발생하고 비교적 빠르게 끝납니다.
- 새로운 객체는 Eden 영역에 할당됩니다.
- Eden 영역이 꽉 차면 Minor GC가 발생합니다.
- Eden 영역에서 살아남은 객체와 기존 Survivor 영역(예: S0)에서 살아남은 객체는 다른 Survivor 영역(예: S1)으로 이동합니다. 이때 객체의 '나이(age)'가 1 증가합니다.
- GC 후 Eden과 사용된 Survivor 영역(S0)은 깨끗하게 비워집니다.
- 다음 Minor GC에서는 S1이 사용 중인 Survivor 영역이 되고, 살아남은 객체는 S0으로 이동합니다.
- 이 과정이 반복되면서 특정 '나이' 이상 살아남은 객체는 Old Generation으로 이동(Promotion)됩니다.
(마치 사용자님이 제공해주신 이미지의 위쪽에서 아래쪽으로 변하는 과정처럼요!)
- Major GC (또는 Full GC): Old Generation에서 발생하는 GC입니다. Old Generation은 상대적으로 오랫동안 살아남은 객체들이 많으므로, Major GC는 Minor GC보다 덜 자주 발생하지만 시간이 더 오래 걸리고 애플리케이션 성능에 큰 영향을 줄 수 있습니다. 🐢 Full GC는 Young Generation과 Old Generation을 포함한 전체 힙 영역을 대상으로 하기도 합니다.

- GC 동작 순서 - 핵심 원리 (Mark, Sweep, Compact)
- GC Root (시작점): 힙 외부에서 내부의 객체를 참조하는 "뿌리"가 되는 참조들을 말합니다. 예를 들어, 실행 중인 스레드의 스택 변수, 네이티브 메소드 스택의 JNI 참조, 메소드 영역의 static 변수 등이 GC Root가 될 수 있습니다.
- Mark (표시): GC Root에서부터 시작하여, 참조 관계를 따라가며 도달 가능한 (살아있는) 객체들을 모두 표시(Mark)합니다. 🚩 마치 친구의 친구를 계속 찾아나가는 과정과 비슷해요.
- Sweep (쓸기): 표시되지 않은 객체들, 즉 GC Root로부터 도달 불가능한 객체들을 메모리에서 제거(Sweep)합니다. 이들이 바로 '쓰레기'입니다. 🧹
- (선택 사항) Compact (압축): Sweep 후 메모리 공간에는 빈 공간(구멍)들이 생겨 단편화가 발생할 수 있습니다. Compact 단계에서는 살아있는 객체들을 한쪽으로 모아 빈 공간을 최소화하여 메모리 단편화를 줄입니다. 📦➡️🧱 (이 과정은 GC 알고리즘에 따라 수행 여부나 방식이 다릅니다.)
- GC는 "쓰레기" 객체를 식별하기 위해 '도달 가능성 분석(Reachability Analysis)' 이라는 방법을 사용합니다.

다양한 GC 친구들은 누가 있을까요? 👨👩👧👦
JVM에는 다양한 GC 알고리즘이 있으며, 각각의 특징과 장단점이 다릅니다. 애플리케이션의 특성에 맞는 GC를 선택하는 것이 중요합니다.
- Serial GC (단순하지만 확실하게! 🚂):
- 동작: 가장 단순한 GC 방식입니다. GC를 처리하는 스레드가 1개(싱글 스레드)이며, GC가 동작하는 동안에는 애플리케이션의 모든 스레드가 멈춥니다 (Stop-the-World). 🛑
- 특징: 간단하고 오버헤드가 적지만, Stop-the-World 시간이 길 수 있습니다. 주로 클라이언트 환경이나 작은 규모의 애플리케이션에 적합합니다.
- Parallel GC (함께하면 빨라요! 🚄🚄):
- 동작: "Throughput GC"라고도 불립니다. Serial GC와 기본 알고리즘은 같지만, Young Generation의 Minor GC를 여러 스레드가 병렬로 처리하여 GC 시간을 단축시킵니다. Old Generation의 Major GC는 여전히 싱글 스레드로 동작할 수 있습니다(Parallel Old GC는 병렬 처리).
- 특징: Stop-the-World는 여전히 발생하지만, Serial GC보다 처리 속도가 빠릅니다. CPU 코어가 여러 개인 서버 환경에서 전체 처리량(Throughput)을 높이는 데 유리합니다. Java 8까지의 기본 GC였습니다.
- CMS GC (Concurrent Mark Sweep - 최대한 멈추지 않도록! 🏃♂️💨):
- 동작: Stop-the-World 시간을 최소화하는 데 초점을 맞춘 GC입니다. 이름에서 알 수 있듯이, Mark와 Sweep 단계의 일부를 애플리케이션 스레드와 동시에(Concurrent) 실행하려고 노력합니다.
- 특징: 응답 속도가 중요한 웹 서버 등에 유리합니다. 하지만 다른 GC 방식보다 CPU를 더 많이 사용하고, 메모리 단편화 문제가 발생할 수 있으며, Compaction 단계를 기본적으로 수행하지 않습니다 (Full GC 시 수행).
- G1 GC (Garbage-First - 미래지향적 해결사! 🤖):
- 동작: 대용량 힙 메모리(보통 4GB 이상)를 위해 설계된 GC입니다. 전체 힙을 바둑판처럼 여러 개의 작은 영역(Region)으로 나누어 관리합니다. GC 시 전체 힙을 대상으로 하지 않고, '쓰레기가 가장 많이 쌓인(Garbage-First)' Region들을 우선적으로 정리합니다.
- 특징: 짧고 예측 가능한 Stop-the-World 시간을 목표로 합니다. CMS의 단편화 문제를 해결하고, 큰 힙에서도 비교적 일정한 GC 성능을 제공합니다. Java 9부터 기본 GC로 채택되었습니다. ✨
이 외에도 ZGC, Shenandoah GC 등 더 발전된 GC 알고리즘들이 계속 등장하고 있습니다!
정리하며 📝
오늘은 JVM의 핵심 기능 중 하나인 가비지 컬렉션(GC)에 대해 알아보았습니다!
- GC란? 🤔: JVM의 자동 메모리 청소부! 힙 영역의 더 이상 사용되지 않는 객체(쓰레기)를 수거하여 메모리를 효율적으로 관리합니다.
- GC 과정 ⚙️:
- Young Generation (Eden, Survivor0, Survivor1): 새로운 객체가 생성되고 Minor GC가 주로 발생합니다. 살아남은 객체는 나이를 먹고, 일정 나이가 되면 Old Generation으로 이동!
- Old Generation: 오랫동안 살아남은 객체들이 머무는 곳. Major GC (또는 Full GC)가 발생합니다.
- GC 동작 원리 🧠:
- GC Root에서 시작!
- Mark: 살아있는 객체에 표시하기.
- Sweep: 표시 안 된 쓰레기 객체 치우기.
- (Optional) Compact: 메모리 단편화 줄이기 위해 압축하기.
- 다양한 GC 친구들 👨👩👧👦: Serial GC, Parallel GC, CMS GC, G1 GC 등 각각의 특징과 목적에 따라 다양한 알고리즘이 존재합니다.
GC를 이해하는 것은 JVM 기반 애플리케이션의 성능 최적화와 안정적인 운영에 있어 매우 중요합니다. 마치 튼튼한 집을 잘 유지보수하는 방법을 배운 것과 같죠! 🛠️
GC의 세계, 생각보다 깊고 흥미롭지 않나요? 😊 처음에는 용어도 많고 복잡해 보일 수 있지만, 차근차근 알아가다 보면 JVM이 어떻게 효율적으로 동작하는지 더 잘 이해하게 될 거예요!

오늘도 새로운 지식을 향한 여정에 함께해주셔서 감사합니다! JVM의 심장 박동을 조금 더 가까이에서 느낄 수 있었기를 바랍니다. 💪
모두 오늘도 정말 수고 많으셨습니다! 다음 시간에도 더욱 흥미롭고 유익한 JVM 이야기로 찾아뵙겠습니다. 즐거운 하루 보내세요! 👋
'데이터 엔지니어링' 카테고리의 다른 글
| 패스트캠퍼스 환급챌린지 49일차: 데이터엔지니어링 초격차 강의 후기 (1) | 2025.05.19 |
|---|---|
| 패스트캠퍼스 환급챌린지 48일차: 데이터엔지니어링 초격차 강의 후기 (1) | 2025.05.18 |
| 패스트캠퍼스 환급챌린지 46일차: 데이터엔지니어링 초격차 강의 후기 (1) | 2025.05.16 |
| 패스트캠퍼스 환급챌린지 45일차: 데이터엔지니어링 초격차 강의 후기 (0) | 2025.05.15 |
| 패스트캠퍼스 환급챌린지 44일차: 데이터엔지니어링 초격차 강의 후기 (0) | 2025.05.14 |