가비지 컬렉션(GC)은 어떻게 메모리를 정리할까

가비지 컬렉션이란?

프로그램이 실행되면 변수, 객체 등을 저장하기 위해 메모리(힙 영역)를 계속 할당받습니다. 그런데 더 이상 사용하지 않는 객체를 개발자가 일일이 해제하지 않으면 메모리가 계속 쌓여 결국 부족해지는 문제가 생깁니다. 가비지 컬렉션(Garbage Collection, GC)은 이렇게 더 이상 참조되지 않는 객체를 자동으로 찾아 메모리에서 제거해주는 기능입니다. Java, Python, JavaScript 같은 언어는 개발자가 직접 free()를 호출하지 않아도 런타임(JVM 등)이 알아서 이 작업을 처리해줍니다.

GC는 어떻게 동작할까

가장 기본이 되는 방식은 Mark and Sweep입니다. 이름 그대로 두 단계로 나뉩니다.

  • Mark(표시): 프로그램이 실제로 사용 중인(참조하고 있는) 객체를 모두 찾아 표시합니다.
  • Sweep(제거): 표시되지 않은, 즉 아무도 참조하지 않는 객체를 메모리에서 지웁니다.

이 과정은 마치 도서관 사서가 정기적으로 서가를 점검하는 것과 비슷합니다. 대출 기록(참조)이 남아있는 책은 그대로 두고, 아무도 빌리지 않고 반납 기록도 없는 낡은 책(참조가 끊긴 객체)만 골라내 폐기하는 것이죠.

대부분의 객체는 생성된 직후 금방 쓸모없어지는 경향이 있어서, JVM 같은 런타임은 메모리를 Young(신생대)Old(구세대) 영역으로 나눠 관리하는 세대별 GC(Generational GC) 방식을 사용합니다. 새로 생긴 객체는 Young 영역에서 자주 검사하고, 오래 살아남은 객체만 Old 영역으로 옮겨 상대적으로 덜 검사함으로써 성능을 높입니다.

실무에서 GC가 중요한 이유

GC 덕분에 개발자는 메모리 해제 코드를 직접 작성하지 않아도 되어 생산성이 크게 올라갑니다. 하지만 공짜는 아닙니다. GC가 동작하는 동안에는 프로그램 실행이 잠시 멈추는 Stop-The-World 현상이 발생할 수 있고, 이 시간이 길어지면 응답 지연으로 이어져 서비스 품질에 직접적인 영향을 줍니다. 그래서 백엔드 개발자는 GC 로그를 분석하거나, JVM 옵션으로 힙 크기와 GC 알고리즘(G1, ZGC 등)을 튜닝하며 지연 시간을 최소화하려고 노력합니다. 결국 GC를 이해한다는 것은 단순히 개념을 아는 것을 넘어, 실제 서비스의 성능과 안정성을 다루는 실무 역량과 직결됩니다.

댓글 남기기