뭐라도 쓰겠지
25.03.28 / 박싱(Boxing)과 언박싱(Unboxing) 본문
C#에서 박싱과 언박싱은 값 형식(Value Type)과 참조 형식(Reference Type) 간의 변환 과정에서 일어나는 중요한 개념이다. 간단히 말해 박싱은 값 형식을 참조 형식으로 변환하는 과정이고, 언박싱은 반대로 참조 형식을 값 형식으로 변환하는 과정이다.
박싱(Boxing)
- 정의: 값 형태(int, float, struct 등)의 데이터를 힙(Heap) 영역에 새로운 객체로 할당하여 object 타입(또는 다른 참조 형식)으로 변환하는 것.
- 예시
int number = 123;
object boxedNumber = number; // 박싱 발생
- 동작 과정
- 1. number라는 값 형식 변수가 스택에 존재함.
- 2. object 타입 변수인 boxedNumber에 nubmer를 대입하면, 런타임에서 힙 영역에 새 객채를 생성하여 값을 복사함.
- 3. boxedNumber는 이 힙 영역의 객체를 참조하게 됨.
- 주의할 점
- 박싱은 추가 메모리 할당과 참조 타입 객체 생성이 필요하기 때문에 오버헤드가 발생한다.
언박싱(Unboxing)
- 정의: object 타입(또는 박싱된 참조 타입)으로부터 원래의 값 형식 데이터를 다시 꺼내는 것.
- 예시
object boxedNumber = 123; // 박싱된 상태
int unboxedNumber = (int)boxedNumber; // 언박싱 발생
- 동작 과정
- 1. boxedNumber는 힙 영역의 object 참조를 가리키고 있음.
- 2. (int)boxedNumber를 통해 원래의 값 형식(int)로 가져오기 위해 형 변환을 수행함.
- 3. 힙에 저장된 데이터를 스택의 unboxedNumber 변수로 복사하여 값 형식으로 되돌림.
- 주의할 점
- 언박싱 시에는 명시적인 형 변환이 반드시 필요하다.
- 만약 잘못된 형식으로 언박싱하려고 하면 InvalidCastException이 발생한다.
- 언박싱 또한 박싱과 마찬가지로 성능 오버헤드가 있으므로 자주 발생하지 않도록 주의해야 한다.
박싱과 언박싱의 영향 및 주의사항
- 성능 이슈
- 박싱할 때마다 힙 영역에 새로운 객체가 생성된다.
- 언박싱할 때마다 형 변환과 값 복사가 일어난다.
- 박싱/언박싱이 과도하면 가비지 컬렉터 부담이 늘어날 수 있다.
- 박싱/언박싱을 줄이는 법
- 1. 제네릭(Generic) 활용: 제네릭 타입을 사용하면 타입 매개변수에 값 형식을 직접 지정해 박싱/언박싱을 줄일 수 있다.
- 2. 값 타입 컬렉션: .NET 6 이상에서는 Span<T>, Memory<T> 같은 구조체 기반의 컬렉션/버퍼를 사용하여 불필요한 객체 생성 및 박싱을 피할 수 있다.
- 3. 적절한 자료 구조 선택: 예를 들어, ArrayList 대신 제네릭 컬렉션(List<T>, Dictionary<TKey, TValue> 등)을 사용하면 박싱/언박싱을 크게 줄일 수 있다.
이처럼 C#에서 박싱과 언박싱은 값 형식을 객체로 사용해야 할 때 불가피하게 일어난다. 반드시 필요한 경우가 아니라면, 제네릭이나 적절한 컬렉션을 사용하여 불필요한 박싱/언박싱을 피하는 것이 권장된다.
'프로그래밍' 카테고리의 다른 글
| 25.03.28 / 패턴 매칭(Pattern Matching) (0) | 2025.03.28 |
|---|---|
| 25.03.28 / IS-A, HAS-A (0) | 2025.03.28 |
| 25.03.28 / LINQ(Language Integrated Query) (0) | 2025.03.28 |
| 25.03.28 / 템플릿(Template), 제네릭(Generic) (0) | 2025.03.28 |
| 25.03.28 / 인터페이스(Interface) (0) | 2025.03.28 |