개발 TIL

내일배움캠프TIL 73일차 정리

yun-wj1126 2025. 5. 14. 21:13

유니티에서 가비지 컬렉터(Garbage Collector, GC)는 C# 및 .NET 기반의 자동 메모리 관리 시스템으로, 더 이상 사용되지 않는 객체를 자동으로 식별하고 메모리를 회수하는 역할을 합니다. 개발자가 직접 메모리를 할당하거나 해제하지 않아도 되기 때문에 메모리 누수 위험이 줄어들고, 코드 작성이 간편해집니다

작동 원리

유니티의 가비지 컬렉터는 주로 Mark-and-Sweep 알고리즘을 사용합니다.

  • 마킹(Marking): GC가 루트 오브젝트(스택, 정적 변수 등)에서 시작해 접근 가능한 객체를 모두 표시합니다.
  • 스위핑(Sweeping): 마킹되지 않은 객체(더 이상 참조되지 않는 객체)를 메모리에서 해제합니다.
  • 컴펙션(Compaction): 남은 객체들을 힙의 시작 부분으로 이동시켜 메모리 단편화를 줄입니다

유니티는 기본적으로 Boehm GC(Stop-the-World 방식)를 사용하며, 2019.1 버전 이후부터는 멈춤 시간을 줄이기 위해 점진적 가비지 컬렉션(Incremental GC) 기능도 제공합니다. 점진적 GC는 여러 프레임에 걸쳐 GC 작업을 분산시켜, 한 번에 프로그램이 멈추는 현상을 완화합니다

특징 및 주의사항

  • 자동 관리: 개발자가 명시적으로 메모리를 해제할 필요 없이, GC가 주기적으로 불필요한 객체를 정리합니다
  • 메모리 누수 방지: 참조가 끊긴 객체는 자동으로 해제되어 메모리 누수를 예방합니다. 단, 이벤트 리스너나 델리게이트 등에서 참조를 명확히 해제하지 않으면 누수가 발생할 수 있습니다
  • 성능 이슈: GC가 동작하는 순간(특히 Boehm GC의 경우) 게임이 잠깐 멈추는 Stop-the-World 현상이 발생할 수 있습니다. 이 때문에 실시간성이 중요한 게임에서는 GC 발생을 최소화하는 것이 중요합니다
  • 최적화 방법:
    • 임시 객체 생성을 줄이고, 오브젝트 풀링(Object Pooling) 기법을 활용합니다.
    • 리스트 등 컬렉션의 크기를 미리 지정해 불필요한 할당을 줄입니다.
    • 문자열 연산은 StringBuilder를 사용해 GC 유발을 줄입니다.
    • 필요 없는 리소스는 Destroy 및 Resources.UnloadUnusedAssets()로 명시적으로 해제합니다

관리되는 메모리와 힙

유니티의 C# 스크립트는 관리되는 힙(Managed Heap)에 동적으로 객체를 할당합니다. GC는 이 힙을 주기적으로 검사해 더 이상 참조되지 않는 객체를 수집합니다

요약

  • 유니티의 가비지 컬렉터는 C#/.NET의 자동 메모리 관리 시스템을 기반으로 하며, 사용하지 않는 객체를 자동으로 정리해줍니다.
  • Mark-and-Sweep 방식과 점진적 GC 등 다양한 방식으로 동작하며, 성능 저하를 막기 위해 최적화가 필요합니다.
  • GC로 인한 일시적 멈춤을 줄이기 위해 객체 생성을 최소화하고, 오브젝트 풀링 등 최적화 기법을 사용하는 것이 좋습니다