💻 프로그래밍

가비지 컬렉션

Garbage Collection

더 이상 사용되지 않는 메모리를 자동으로 해제하는 메모리 관리 기법. Java, Python, Go 등에서 사용.

📖 상세 설명

가비지 컬렉션(GC)은 프로그램이 동적으로 할당한 메모리 중 더 이상 사용하지 않는 부분을 자동으로 찾아 해제하는 메모리 관리 기법입니다. C/C++처럼 수동으로 메모리를 관리하는 언어와 달리, Java, Python, Go, JavaScript 등은 GC를 통해 메모리 누수와 댕글링 포인터 문제를 방지합니다.

GC의 기본 원리는 "도달 가능성(Reachability)"입니다. 루트(전역 변수, 스택, 레지스터)에서 참조 체인을 따라 접근 가능한 객체는 살아있는 것으로 간주하고, 접근할 수 없는 객체는 가비지로 판단하여 수거합니다.

대표적인 GC 알고리즘으로는 Mark-and-Sweep(도달 불가능한 객체를 표시 후 제거), Reference Counting(참조 횟수가 0이 되면 제거), Generational GC(객체를 세대별로 나누어 관리) 등이 있습니다. Java의 G1GC, ZGC나 Go의 Concurrent GC는 애플리케이션 중단 시간을 최소화하도록 설계되었습니다.

GC는 편리하지만 "Stop-the-World" 현상으로 일시적인 성능 저하가 발생할 수 있습니다. 따라서 실시간 시스템이나 저지연이 중요한 애플리케이션에서는 GC 튜닝이나 메모리 풀링 같은 기법을 함께 사용합니다.

💻 코드 예제

JavaScript
// 가비지 컬렉션의 동작 원리 이해

// 1. 객체가 생성되어 메모리에 할당됨
let user = {
    name: "김개발",
    data: new Array(1000000).fill("데이터")
};

// 2. user 변수가 객체를 참조하고 있어 GC 대상이 아님
console.log(user.name);  // "김개발"

// 3. 참조를 제거하면 GC 대상이 됨
user = null;  // 이제 원래 객체에 접근할 방법이 없음

// 4. GC가 동작하면 해당 메모리가 해제됨
// (정확한 시점은 런타임이 결정)

// WeakMap/WeakSet - 약한 참조로 GC 허용
const cache = new WeakMap();
let obj = { id: 1 };
cache.set(obj, "캐시된 값");

obj = null;  // obj에 대한 강한 참조가 없어지면
// WeakMap의 항목도 GC 대상이 됨

// 순환 참조 - 현대 GC는 처리 가능
function createCircular() {
    const a = {};
    const b = {};
    a.ref = b;
    b.ref = a;
    // 함수 종료 후 a, b 모두 도달 불가능 → GC 대상
}

🗣️ 실무 대화 예시

백엔드 개발자
"프로덕션에서 GC 일시 정지 시간이 200ms까지 올라가는 경우가 있어요. 응답 지연이 발생하는데 어떻게 해결할까요?"
시니어 개발자
"G1GC에서 ZGC로 전환하면 일시 정지 시간을 10ms 이하로 줄일 수 있어요. 다만 메모리 오버헤드가 조금 증가합니다."
백엔드 개발자
"객체 생성을 줄이는 것도 방법이겠네요. 자주 생성되는 DTO들은 오브젝트 풀로 재사용하는 건 어떨까요?"
면접관
"Java의 Generational GC에서 Young Generation과 Old Generation을 나누는 이유가 무엇인가요?"
지원자
"대부분의 객체는 생성 직후 빠르게 소멸된다는 '약한 세대 가설'에 기반합니다. Young 영역을 자주 수거하면 효율적이고, 오래 살아남은 객체는 Old로 옮겨 수거 빈도를 줄입니다."
면접관
"메모리 누수가 GC 환경에서도 발생할 수 있나요?"
지원자
"네, 의도치 않은 참조 유지로 발생합니다. 예를 들어 static 컬렉션에 객체를 추가만 하고 제거하지 않거나, 클로저가 외부 변수를 불필요하게 캡처하는 경우입니다."
리뷰어
"이 루프에서 매번 새 StringBuilder를 생성하고 있네요. 루프 밖에서 한 번 생성하고 재사용하면 GC 부담을 줄일 수 있어요."
작성자
"아, 맞아요. clear() 메서드로 내용만 비우고 재사용하도록 수정하겠습니다."
리뷰어
"그리고 이 HashMap은 사용 후 참조를 null로 설정하거나 스코프를 좁히면 더 빨리 GC 대상이 될 거예요."

⚠️ 주의사항

🔗 관련 용어

📚 더 배우기