"깊이"가 다른 게임개발자 허민영

유저에서 게임까지, 철학에서 코딩까지, 본질을 보는 게임개발

소프트웨어 공학/코딩

박싱과 언박싱에 메모리에서 일어나는 과정

허민영 2025. 4. 23. 22:33

박싱(Boxing)은 값 형식(Value Type)을 참조 형식(Reference Type)으로 변환하는 과정이다. C#에서 int, struct 등 값 형식은 기본적으로 스택(Stack)에 직접 저장된다. 그러나 박싱이 발생하면 CLR(또는 Unity의 Mono/IL2CPP 런타임)이 다음 절차로 힙(Heap)에 객체를 생성하고 값을 복사한다.

  1. 힙 영역에 객체 헤더(Object Header) 및 내부 저장소를 위한 메모리 할당
  2. 스택의 값 형식 비트를 힙 객체의 내부 필드에 복사
  3. 힙 객체의 주소(참조 Reference)가 스택 변수 영역에 저장

힙 객체는 내부에 sync block, 타입 메타데이터 포인터 등 런타임 관리 정보를 포함하며, 32비트 환경에서는 객체 헤더만으로 8바이트 내외의 추가 오버헤드가 발생한다.

언박싱(Unboxing)은 힙에 박싱된 객체에서 값 형식을 추출하여 다시 스택에 복사하는 과정을 의미한다. 언박싱 시에는 타입 안정성을 위해 다음 절차를 거친다.

  1. 스택에 저장된 참조 값을 읽어 힙 객체 주소 확인
  2. 힙 객체 헤더의 타입 메타데이터와 대상 값 형식의 타입을 비교하여 일치 여부 검사
  3. 내부 저장소에 보관된 값을 스택의 값 형식 변수 영역으로 복사

이때 언박싱 연산자는 런타임 검사와 복사 작업을 수행하므로 단일 연산에도 일정 비용이 발생한다.

void Example()
{
    int value = 42;                // 값 형식, 스택에 저장
    object boxed = value;          // 박싱: 힙에 int 객체 할당 및 복사, 참조 반환
    int unboxed = (int)boxed;      // 언박싱: 참조를 읽어 힙에서 복사, 타입 검사 수행
}

 

Unity 환경에서는 잦은 박싱/언박싱이 가비지 컬렉션(GC) 횟수 및 메모리 할당량을 증가시켜 프레임 드랍 등의 성능 저하를 초래할 수 있다. 따라서 제네릭 컬렉션(List<T>), Span<T>, 구조체 기반 루프, C# Job System 등을 활용하여 값 형식을 그대로 처리하거나, 박싱이 일어나지 않도록 코드 구조를 설계하는 것이 권장된다.

결론적으로 박싱과 언박싱은 스택과 힙 간 비트 복사 및 런타임 타입 관리 정보를 포함하는 메모리 변환 과정이다. Unity 개발 시 메모리 오버헤드와 GC 부담을 고려하여 불필요한 박싱을 최소화하면, 안정적인 프레임 성능을 유지할 수 있다.

'소프트웨어 공학 > 코딩' 카테고리의 다른 글

TCP와 UDP비교  (0) 2025.04.25
리플렉션 Reflection  (0) 2025.04.24
Unity] GetComponent를 최소한으로 사용해야하는 이유  (0) 2025.04.22
Unity] Assembly Definition  (0) 2025.04.21
Unity] Addressables  (0) 2025.04.18