유니티 가비지 컬렉션

PTK·2025년 2월 20일
0

가비지 컬렉션(GC, Garbage Collection)은 프로그래밍에서 사용이 끝난 메모리를 자동으로 회수하는 기능을 의미합니다. Unity는 .NET의 GC 시스템을 기반으로 메모리를 관리하며, GC가 실행되면 일시적인 성능 저하(프레임 드랍, CPU 스파이크 등) 가 발생할 수 있다.

1. 가비지 컬렉션의 기본 개념

C#에서는 스택(Stack)과 힙(Heap) 두 가지 메모리 영역을 사용합니다.

new 키워드로 생성된 객체는 힙(Heap) 메모리에 할당되며, 더 이상 참조되지 않으면 GC가 이를 정리한다.

가비지 컬렉션의 동작 과정_

가비지 컬렉션은 더 이상 참조되지 않는 객체(사용하지 않는 메모리)를 탐색하고 해제하는 방식으로 동작한다.

  1. 루트(Root) 객체 탐색

    여전히 사용 중인 객체들을 찾는다.

    참조가 없는 객체를 "가비지(불필요한 데이터)"로 간주한다.

  2. 가비지 객체 삭제

    참조가 끊어진 객체를 삭제하여 메모리를 회수한다다.

  3. 메모리 단편화 정리(Compaction, 압축)

    메모리가 조각나지 않도록 정리하여 공간을 최적화한다.

2. 유니티에서 가비지 컬렉션의 문제점

유니티에서는 가비지 컬렉션이 실행될 때 일시적으로 게임이 멈추는 현상(GC Spike) 이 발생할 수 있다.

가비지 컬렉션의 실행 조건_

  1. 힙(Heap) 메모리가 부족할 때

  2. 일정한 할당 임계값을 초과할 때

  3. 강제로 가비지 컬렉션을 실행 시 ( GC.Collect() )

하지만, 가비지 컬렉션은 동기적으로 실행되므로 가능하면 강제 실행을 피하는 것이 좋다.

3. 가비지 컬렉션의 문제를 줄이는 방법

  1. new 키워드 사용 최소화
void Update() 
{
    Vector3 pos = new Vector3(0, 0, 0); // 매 프레임마다 객체 생성 (GC 부담 증가)
}

해결 방법

private Vector3 pos = new Vector3(0, 0, 0);

void Update()
{
    pos.Set(0, 0, 0); // 기존 객체 재사용
}
  1. string 대신 StringBuilder 사용
string message = "Score: " + score.ToString();  // GC 부담 증가

해결 방법

StringBuilder sb = new StringBuilder();
sb.Append("Score: ").Append(score);
  1. 오브젝트 풀링(Object Pooling) 사용

자주 생성/삭제되는 객체(총알, 이펙트 등)는 오브젝트 풀링 기법을 사용하여 메모리 할당을 줄인다.

Queue<GameObject> pool = new Queue<GameObject>();

GameObject GetObject() 
{
    if (pool.Count > 0) 
    {
        GameObject obj = pool.Dequeue();
        obj.SetActive(true);
        return obj;
    }
    
    return Instantiate(prefab);
}

void ReturnObject(GameObject obj) 
{
    obj.SetActive(false);
    pool.Enqueue(obj);
}
  1. 메모리 풀링(Memory Pooling) 사용

메모리 풀링은 Heap 메모리를 할당하는 대신, 미리 확보한 메모리 블록을 재사용하는 방식이다.

주로 배열, 버퍼, 구조체 같은 데이터를 관리할 때 사용된다.

메모리 단편화를 해결하는 방법중 하나이다.

C#에서 ArrayPool 같은 기능이 메모리 풀링을 구현하는 대표적인 방식이다.

using System.Buffers;

int[] array = ArrayPool<int>.Shared.Rent(100); // 메모리 대여
// 배열 사용...
ArrayPool<int>.Shared.Return(array); // 메모리 반환 (GC 부담 감소)
  1. Incremental GC(증분 가비지 컬렉션)

유니티 2019 버전이후 추가된 기능이다.

한 번에 모든 GC 작업을 수행하는 것이 아니라, 여러 프레임에 걸쳐 조금씩 실행하여 성능을 개선한다.

활성화 방법:

Edit → Project Settings → Player → Use Incremental GC 활성화

0개의 댓글