Unity/정보

[Unity] 유니티의 가비지 콜렉터 (G.C)

달시_Dalsi 2024. 9. 16. 16:06

가비지 콜렉터란?

가비지 콜렉터(GC)는 프로그램에서 더 이상 필요하지 않은 메모리(가비지)를 자동으로 회수하여 메모리 누수를 방지하고 메모리를 관리하는 시스템입니다. 유니티는 C#을 사용하여 스크립트를 작동하며 .NET의 가비지 콜렉터를 기반으로 메모리를 관리합니다. 

 

 

작동 방식

가비지 콜렉션은 주로 C#에서 관리되는 힙 메모리에서 이루어집니다. Unity는 생성된 객체가 더 이상 사용되지 않을 때 자동으로 메모리에서 해제하는데, 메모리에서 해제되는 시점을 완벽하게 제어하기는 어렵습니다. 그리고 GC는 메모리를 세대별로 나누어 오래된 객체와 최근에 생성된 객체를 구분해서 관리합니다.

  • 0세대 (Gen 0): 가장 최근에 생성된 객체들이 위치하며, 수명이 짧은 객체가 많습니다. 이 세대는 빠르게 메모리에서 제거됩니다.
  • 1세대 (Gen 1): Gen 0에서 살아남은 객체들이 이곳으로 이동합니다. 여기에 속한 객체는 중간 정도의 수명을 가집니다.
  • 2세대 (Gen 2): 장기적으로 살아남은 객체들은 이 세대에 배치됩니다. 자주 수집되지 않으며, 장기적으로 유지되는 객체들을 위한 메모리 공간입니다.

 

가비지 콜렉터 최적화 방법

  1. 메모리 할당 최소화:
    • 매 프레임마다 메모리를 할당하거나 해제하는 것을 피하고, 메모리 풀링을 사용하여 객체를 재사용합니다.
    • Object Pooling을 통해 객체의 생성을 줄이고, 가비지 콜렉션의 부담을 경감할 수 있습니다.
  2. 가비지 생성 방지:
    • 구조체를 사용하고, string의 불필요한 생성을 피합니다.
    • List와 같은 것을 사용할 때, 가능하면 Array를 사용하는 것이 좋습니다.
  3. GC 관련 설정 조정:
    • Unity Profiler를 사용하여 GC의 성능을 모니터링하고, 필요에 따라 GC 관련 설정을 조정합니다.
    • 설정을 통해 GC 호출 시점을 조절할 수 있습니다.

 

유니티의 가비지 콜렉터 응용 방법 및 스크립트 활용

1. 가비지 콜렉터 이해 및 모니터링

가비지 콜렉터(GC)를 효과적으로 활용하려면 먼저 어떻게 작동하는지 이해하고 모니터링하는 것이 중요합니다.

  • GC 모니터링: 유니티의 Profiler를 사용하여 가비지 콜렉터의 성능을 모니터링할 수 있습니다. Profiler는 GC가 발생할때 시각적으로 표시하고, GC로 인한 프레임 드롭을 분석하는 데 도움을 줍니다.
  • Memory Profiler: Unity의 Memory Profiler를 사용하여 메모리 사용량을 분석하고 GC 관련 문제를 확인할 수 있습니다.

2. 가비지 콜렉션 최적화

최적화를 통해 GC의 성능 영향을 최소화할 수 있습니다. 몇 가지 방법을 소개합니다:

  • 객체 풀링: 자주 생성되고 파괴되는 객체를 미리 생성해두고 재활용하는 방법입니다. 이 방식은 메모리 할당과 해제를 줄여 GC의 부담을 경감시킵니다.
  • 메모리 할당 최소화: List와 같은 동적 컬렉션을 사용할 때, Array로 대체하거나 사용 후 메모리를 명시적으로 해제하여 GC의 부담을 줄입니다. 또한, string을 자주 생성하는 것을 피하는 것이 좋습니다.
  • 배열 및 구조체 활용: 가능한 경우 struct를 사용하여 힙 메모리 할당을 줄입니다. struct는 값 타입으로 스택 메모리에 저장되므로 GC의 부담을 줄일 수 있습니다.

3. 가비지 콜렉션을 피하는 스크립트 작성 방법

  • 로컬 변수 활용: 메서드 내에서 사용하는 변수는 로컬로 선언하여 메모리 할당을 줄입니다. 
  • 상수 및 readonly 사용: 변경되지 않는 값은 const 또는 readonly로 선언하여 메모리 할당을 줄입니다.
  • 메모리 할당과 해제 최소화: 업데이트 루프에서 new 연산자 사용을 최소화하고, 메모리 할당과 해제를 줄이는 것이 중요합니다. 예를 들어, Update 메서드에서 객체를 생성하는 것은 피해야 합니다.
  • 빠른 메모리 접근: List<T> 보다는 NativeArray<T> 같은 Unity의 Native Collections를 사용하여 빠르고 효율적인 메모리 접근이 가능합니다. 이 방법은 GC의 영향을 줄이고 성능을 향상시킬 수 있습니다.

4. GC 관련 Unity 설정

  • GC.Collect(): GC.Collect()를 명시적으로 호출하여 메모리를 강제로 정리할 수 있지만, 이 방법은 성능에 영향을 미칠 수 있으므로 필요한 경우에만 사용합니다.
  • Job System 및 Burst Compiler: Unity의 Job System과 Burst Compiler를 활용하여 멀티스레딩을 통해 작업을 분산하고 GC의 부담을 줄일 수 있습니다. 이 방법은 메모리 할당과 해제를 최적화하고 성능을 개선합니다.

결론

유니티의 가비지 콜렉터는 메모리 관리를 자동화하여 개발자의 부담을 줄여주지만, 게임 성능에 영향을 미칠 수 있는 중요한 요소입니다. 이를 효과적으로 관리하고 최적화하기 위해서는 메모리 할당을 최소화하고, GC 성능을 모니터링하며 가비지 콜렉션의 부담을 줄이는 것이 중요합니다.