SW/면접

가비지 컬렉션이란? 초보 개발자를 위한 쉬운 개념 정리

얇은생각 2025. 4. 3. 07:30
반응형

혹시 이런 경험 있나요? 프로그램을 열었는데 갑자기 버벅거리거나 심지어 튕겨버리는 경우! 사실 이게 다 메모리 관리 문제 때문일 수도 있어요. 컴퓨터가 프로그램을 실행하면서 쓰는 메모리는 한정되어 있는데, 계속해서 쌓이기만 하면 결국 터질 수밖에 없죠. 그래서 등장한 게 바로 가비지 컬렉션(GC)! 오늘은 이 친구가 왜 중요한지, 어떻게 동작하는지, 그리고 각 프로그래밍 언어에서는 어떻게 활용하는지 쉽게 풀어볼게요.

 

가비지 컬렉션이란? 초보 개발자를 위한 쉬운 개념 정리

 

가비지 컬렉션이 뭐길래 이렇게 중요할까?

컴퓨터가 프로그램을 실행하면 여러 개의 변수를 만들고 데이터를 저장하죠. 그런데 사용이 끝난 데이터가 그대로 남아있으면? 결국 메모리만 차지하고 필요 없는 짐이 됩니다. 이걸 정리해 주는 게 바로 가비지 컬렉션이에요. 만약 이걸 개발자가 일일이 정리해야 한다면? 상상만 해도 끔찍하죠. 메모리 해제를 깜빡하면 메모리 누수가 발생하고, 프로그램이 느려지거나 심하면 아예 멈춰버릴 수도 있어요.

 

그렇다면 가비지 컬렉션이 가져다주는 혜택은 뭘까요?

  • 메모리 누수 방지: 안 쓰는 메모리는 자동으로 정리!
  • 성능 최적화: 쓸데없는 메모리 차단으로 프로그램 속도 유지
  • 코딩 스트레스 감소: 메모리 관리 대신 로직 구현에 집중할 수 있음

 

가비지 컬렉션은 어떻게 작동할까?

  • GC는 프로그램이 사용 중인 데이터를 계속 확인하며 필요 없는 데이터를 정리함
  • **GC 루트(GC Roots)**를 기준으로 살아있는 데이터를 식별하고 유지함
  • 접근 불가능한 데이터는 정리하여 메모리를 확보함

 

GC는 "이 데이터 아직 필요해?"라는 질문을 계속해서 던집니다. 이를 위해 **GC 루트(GC Roots)**라는 개념이 등장하는데요, 쉽게 말해 프로그램이 꼭 필요로 하는 데이터(전역 변수, 스택 참조 등)를 기준으로 살아있는 데이터를 찾는 거예요.

GC는 이렇게 접근 가능한 데이터를 유지하고, 그렇지 않은 데이터는 싹 정리합니다. 마치 대청소할 때 "이거 필요해? 버릴까?"를 반복하는 것과 비슷하죠.

 

세대별 가비지 컬렉션? 이게 또 뭐야?

  • GC는 객체의 수명을 기준으로 다른 방식으로 관리함
  • 자주 생성되고 빠르게 삭제되는 데이터와 오랫동안 유지되는 데이터를 구분함

 

효율적인 메모리 관리를 위해 GC는 데이터의 "수명"을 기준으로 관리하는 방식을 사용해요. 즉, 오래 살아남은 데이터와 금방 없어지는 데이터를 구분하는 거죠.

 

 

자바의 메모리 모델

자바는 크게 세 개의 영역으로 나뉘어요:

  1. 영(Young) 세대: 새로 생성된 데이터가 여기에 모임
    • Eden 영역: 처음 만들어진 객체들이 여기에 저장됨
    • Survivor 영역: 몇 번의 GC를 살아남은 객체들이 이동
  2. 노인(Old) 세대: 오래된 객체들이 자리 잡는 곳
  3. 메타스페이스(Metaspace): 프로그램 자체의 메타정보(클래스, 메서드 정보 등)를 저장하는 공간

 

다른 언어에서는 어떻게 할까?

  • JavaScript (V8 엔진): 두 개의 세대로 단순하게 관리
  • .NET GC: 0, 1, 2 총 세 개의 세대로 나누어 관리

 

마크 앤 스위프 알고리즘, 쉽게 설명해줄게!

GC가 메모리를 정리할 때 많이 쓰는 방식 중 하나가 **마크 앤 스위프(Mark-and-Sweep)**인데요, 말 그대로 "마킹하고 쓸어버리는" 과정이에요.

  1. 마킹(Marking): 살아있는 데이터들을 표시
  2. 스위핑(Sweeping): 표시되지 않은 데이터를 삭제

 

하지만 이 방식에는 문제가 있어요. 프로그램을 실행하는 도중 GC가 작동하면 **일시 정지(stop-the-world)**가 발생할 수 있어요. 마치 청소를 하느라 집 안에서 아무도 움직일 수 없는 상황과 비슷하죠.

 

그래서 개선된 방법이 등장했어요: 삼색 마크 앤 스위프!

이 방식에서는 데이터를 세 가지 색깔로 구분합니다:

  • 화이트(White): 필요 없는 데이터 (삭제 대상!)
  • 그레이(Gray): 아직 정리 중인 데이터
  • 블랙(Black): 프로그램에서 사용 중인 데이터

 

이 방식 덕분에 GC가 작동할 때 프로그램이 완전히 멈추지 않고 단계적으로 진행할 수 있어요.

 

프로그래밍 언어별 가비지 컬렉션

자바의 GC 알고리즘

자바는 다양한 GC 옵션을 제공해요:

  • Serial GC: 단일 스레드 방식, 작은 프로그램에 적합
  • Parallel GC: 멀티 스레드 활용, 성능 향상
  • CMS (Concurrent Mark-Sweep): 애플리케이션 멈춤 최소화, CPU 부담 증가 가능
  • G1 GC: 대형 애플리케이션 최적화, 지연 시간 최소화

 

파이썬의 메모리 관리

파이썬은 다음 두 가지 방법을 조합해 사용해요:

  • 참조 카운팅(Reference Counting): 참조가 0이 되면 자동 삭제
  • 순환 GC(Cyclic GC): 순환 참조 문제 해결

 

Go의 GC 방식

Go는 **동시성 마크 앤 스위프(Concurrent Mark-and-Sweep)**를 사용해요. 즉, 프로그램이 실행되는 동안에도 자연스럽게 메모리를 정리하는 방식이죠.

 

가비지 컬렉션의 단점도 있을까?

  • GC 실행 시 프로그램이 잠시 멈출 가능성이 있음
  • 메모리 단편화가 발생하여 할당 속도가 저하될 수 있음
  • GC 타이밍을 개발자가 직접 조정하기 어려움

 

아무리 좋은 기능이라도 단점이 없는 건 아니죠.

  • 퍼포먼스 이슈: GC가 실행될 때 프로그램이 잠깐 멈출 수도 있음
  • 메모리 단편화: 일부 GC는 사용 후 빈 공간이 많아져 할당 속도가 느려질 수도 있음
  • 예측 불가한 실행 시점: 개발자가 GC 타이밍을 정확히 조정하기 어려움

 

마무리하며...

가비지 컬렉션 덕분에 개발자는 메모리 관리 걱정 없이 코딩할 수 있어요. 하지만 GC 방식마다 장단점이 있으니, 프로그램의 특성에 맞는 GC를 선택하는 게 중요하죠. 개발을 하다 보면 "이 프로그램이 왜 이렇게 느려졌지?" 싶은 순간이 있을 텐데, 그럴 때 GC를 의심해 보는 것도 방법이에요!

반응형