Q. Garbage Collection에 대해 설명해주세요.
A. 프로그래밍에서 객체나 변수를 만들면, 그 객체는 마치 책상 위에 물건을 올려두는 것처럼 메모리 공간을 차지하게 됩니다. 그런데 더 이상 사용되지 않거나 아무도 참조하지 않는 객체가 계속 메모리에 남아 있으면, 마치 쓰지 않는 물건이 책상을 차지하고 있어서 새로운 물건을 둘 자리가 없는 것과 같습니다. 이런 상태가 계속되면 메모리 누수가 발생하고, 프로그램의 성능이나 안정성에 치명적이며, 새로운 작업에 필요한 공간을 확보할 수 없어 메모리가 비효율적으로 낭비됩니다.
그래서 Garbage Collection(가비지 컬렉션)은 “더는 쓰지 않는 메모리를 자동으로 찾아서 비워 주는” 메모리 관리 기법입니다. 자바 같은 언어에서는 프로그래머가 직접 delete나 free 같은 코드를 쓰지 않고도, JVM이 주기적으로 사용하지 않는 객체를 찾아서 힙 메모리에서 해제해 줍니다.
여기서 메모리 누수란?
간단하게 설명하자면, 프로그램에서 더는 쓰지 않는 객체들이 메모리에 남아 있어서 (“누수”처럼) 해제되지 않는 현상을 말합니다. 결국 사용 가능한 메모리가 줄어들어 프로그램이 비정상 종료되거나 느려질 수 있습니다.
가장 대표적인 구현 방식은 다음과 같습니다.
참조 카운팅(Reference Counting)
객체에 “이 객체를 참조하는 변수가 몇 개인가”를 숫자로 기록해 두었다가, 참조 수가 0이 되면 즉시 메모리를 회수합니다.
장점: 객체가 참조가 끊어지는 순간 바로 메모리를 해제하므로 간단합니다.
단점: 순환 참조(A가 B를, B가 A를 참조하는 구조)가 있으면 참조 수가 0이 되지 않아 메모리가 해제되지 않는 문제가 발생합니다.
여기서 순환 참조란?
두 개 이상의 객체가 서로를 가리키며 고리(순환)를 이루는 것을 의미합니다.
예를 들어 객체 A가 B를 참조하고, B가 다시 A를 참조하는 구조를 말합니다. 이때 참조 수만 따지면 둘 다 1 이상이어서 절대 0이 되지 않습니다.
>> 그렇기에 참조 카운팅 방식의 단점이 된다.
Q. 그렇다면 GC는 자바에서는 어떻게 동작하나요?
A. 자바에서는 Garbage Collection이 완전히 자동으로 이루어지며, 개발자가 코드를 통해 객체 해제를 직접 호출하지 않아도 JVM이 알아서 처리합니다. 그 동작 과정을 간단히 정리해 보면 다음과 같습니다.
1.객체 할당 → 힙(Heap) 메모리
- 자바 프로그램이 객체를 생성하면, JVM은 힙 메모리에 그 객체를 할당합니다.
- 힙 메모리는 크게 두 영역으로 나뉩니다: Young Generation과 Old Generation.
여기서 힙 메모리(Heap Memory)란?
간단하게 설명하자면, 프로그램이 실행되는 동안 객체가 동적으로 위치하는 메모리 공간을 말합니다. JVM 내부에서 모든 인스턴스와 배열이 이 힙 영역에 저장됩니다.
2. Young Generation(신생 영역)
- 새로 생성된 객체는 처음에 무조건 Young 영역에 들어갑니다.
- 대부분 객체는 금방 참조가 끊어지고 사라지는 특성이 있기 때문에, 이 영역에서 Copying Collection(복사 수집) 방식의 GC가 자주 일어납니다.
- Minor GC라고 부르며, 비교적 짧은 시간에 실행되어 성능 부담이 적습니다.
여기서 Minor GC란?
간단히 말하면 Young Generation 영역에서만 일어나는 가비지 컬렉션을 뜻합니다. 대부분 새로 생성된 객체가 곧바로 사라지기 때문에 짧은 시간 동안만 실행됩니다.
3.Old Generation(구세대 영역)
- Young 영역에서 여러 번 살아남은(참조가 일정 횟수 이상 유지된) 객체는 JVM이 “오래 쓸 가능성이 높다”고 판단해 Old Generation으로 옮깁니다.
- Old 영역은 크기가 크고, 복사 수집보다는 Mark and Sweep 방식(GC 과정 중 메모리 Compaction을 덧붙일 수도 있음)이 더 많이 사용됩니다.
- 이때 발생하는 GC를 Major GC 또는 Full GC라고 부릅니다.
- Stop-the-World라 불리는 현상이 발생할 수 있는데, 이건 GC가 수행되는 동안 애플리케이션(모든 애플리케이션 스레드)이 잠깐 멈추는 것을 의미합니다.
여기서 Stop-the-World란?
간단하게 설명하자면, GC가 수행되는 동안 “모든 애플리케이션 스레드가 일시 중단”되는 현상입니다. 이런 동안에는 애플리케이션이 잠시 응답하지 않으므로, 서비스 지연이나 지연 시간(Latency)이 문제될 수 있습니다.
전체 흐름 요약
- 객체 생성 → Young 영역에 할당
- Young 영역에서 자주 Minor GC 발생 → 살아남은 객체를 Old 영역으로 이동
- Old 영역에서 가끔 Major/Full GC 발생 → Mark & Sweep(또는 Compact)로 불필요한 객체 회수
- 회수된 공간은 빈틈(Fragmentation) 없이 빈 상태로 남아서, 새 객체를 그곳에 할당하거나 Young 영역으로 복사할 때 사용
이렇게 JVM은 자동으로 GC를 관리하여, 개발자는 객체 소멸을 위해 delete 같은 코드를 따로 쓸 필요 없이 메모리를 안전하게 재활용할 수 있습니다.
'CS 공부 > Java' 카테고리의 다른 글
| [기술 면접] Java의 메모리 구조에 대해 이해하기 (2) | 2025.06.08 |
|---|---|
| [기술 면접]Java Generic 이해하기2 (0) | 2025.06.02 |
| [기술 면접]Java Generic 이해하기1 (0) | 2025.06.02 |