-
C# 프로그래밍의 기초: Boxing과 Unboxing2024년 10월 12일
- 유니얼
-
작성자
-
2024.10.12.:25
728x90C#에서 Boxing과 Unboxing은 값 타입과 참조 타입 간의 변환을 다루는 중요한 개념입니다. 이 두 과정은 C#의 데이터 형식 처리 방식에서 발생하는 성능 이슈와 메모리 관리를 이해하는 데 필수적인 요소입니다. 이번 블로그 글에서는 Boxing과 Unboxing의 개념을 설명하고, 실제로 어떻게 동작하는지 예제를 통해 알아보겠습니다.
Boxing이란?
Boxing은 값 타입(Value Type)을 참조 타입(Reference Type)으로 변환하는 과정입니다. C#에서 모든 값 타입(예: int, bool, char)은 스택에 저장되지만, 참조 타입은 힙에 저장됩니다. 값 타입을 참조 타입으로 변환할 때, 값은 힙에 저장되고, 그 값을 가리키는 참조가 생성됩니다. 이 과정을 Boxing이라고 합니다.
Boxing의 과정
- 값 타입의 값을 힙 영역에 할당된 객체에 넣고, 해당 객체의 참조를 반환합니다.
- 이 과정에서 스택에 있던 값이 힙으로 이동하고, 참조가 스택에 남습니다.
Boxing 예제
int number = 123; object obj = number; // Boxing 발생
위 코드에서 number는 값 타입인 int이고, obj는 참조 타입인 object입니다. number 값을 obj로 변환할 때 Boxing이 발생하며, number의 값이 힙 영역에 복사되고, obj는 그 값을 참조하게 됩니다.
Unboxing이란?
Unboxing은 Boxing된 참조 타입을 다시 값 타입으로 변환하는 과정입니다. Boxing과 반대로, 힙에 저장된 값 타입을 다시 스택으로 복사하여 값을 복원하는 작업입니다. Unboxing은 명시적으로 수행해야 하며, Boxing된 참조를 올바른 값 타입으로 변환하지 않으면 오류가 발생할 수 있습니다.
Unboxing의 과정
- 참조 타입으로 Boxing된 값을 다시 값 타입으로 변환하여 스택에 복사합니다.
- 변환할 타입이 정확히 맞지 않으면 InvalidCastException 예외가 발생할 수 있습니다.
Unboxing 예제
object obj = 123; // Boxing int number = (int)obj; // Unboxing
위 예제에서 obj는 Boxing된 int 값입니다. 이를 다시 int로 변환할 때, 명시적인 캐스팅 (int)가 필요하며, 이때 Unboxing이 발생합니다.
Boxing과 Unboxing의 성능 문제
Boxing과 Unboxing은 간단해 보이지만, 성능 상의 이슈가 발생할 수 있습니다. 특히, Boxing은 힙 메모리 할당과 GC(Garbage Collection)의 부담을 초래할 수 있으며, Unboxing은 Boxing된 값을 다시 스택으로 복사하는 비용이 발생합니다. 이러한 변환이 빈번하게 발생할 경우 성능 저하를 유발할 수 있으므로 주의가 필요합니다.
성능 문제를 줄이는 방법
- 값 타입을 필요 이상으로 Boxing하지 않도록 주의합니다.
- ArrayList와 같은 컬렉션 대신 List<T> 같은 제네릭 컬렉션을 사용하면 Boxing을 방지할 수 있습니다.
// Boxing 발생 ArrayList arrayList = new ArrayList(); arrayList.Add(123); // int가 object로 Boxing됨 // Boxing 방지 List<int> list = new List<int>(); list.Add(123); // 값 타입 그대로 처리됨
Boxing과 Unboxing의 실전 예제
using System; namespace BoxingUnboxingExample { class Program { static void Main(string[] args) { // Boxing 예시 int num = 10; object obj = num; // Boxing 발생 Console.WriteLine($"Boxing: num = {num}, obj = {obj}"); // Unboxing 예시 object obj2 = 20; int num2 = (int)obj2; // Unboxing 발생 Console.WriteLine($"Unboxing: obj2 = {obj2}, num2 = {num2}"); // Boxing/Unboxing 성능 테스트 int sum = 0; object boxedNum; for (int i = 0; i < 1000000; i++) { boxedNum = i; // Boxing 발생 sum += (int)boxedNum; // Unboxing 발생 } Console.WriteLine($"Final sum: {sum}"); } } }
위 예제는 Boxing과 Unboxing의 기본적인 동작 원리를 보여줍니다. num 값이 object로 Boxing되고, 이후에 obj2 값이 다시 int로 Unboxing됩니다. 마지막 루프에서는 Boxing과 Unboxing이 빈번하게 발생하며, 이런 경우 성능 상의 부담이 클 수 있음을 보여줍니다.
결론
Boxing과 Unboxing은 값 타입과 참조 타입 간의 변환을 처리하는 C#의 중요한 개념입니다. Boxing은 값 타입을 참조 타입으로 변환하여 힙에 저장하고, Unboxing은 이를 다시 값 타입으로 변환합니다. 그러나 이러한 변환 과정은 성능에 부정적인 영향을 줄 수 있으므로, 불필요한 Boxing과 Unboxing을 피하는 것이 중요합니다. 제네릭 컬렉션이나 값 타입을 최대한 값으로 처리하는 방식으로 성능 문제를 줄일 수 있습니다.
값 타입과 참조 타입 간의 상호 변환을 이해하고, 적절히 사용하는 것이 C# 프로그래밍의 효율성을 높이는 데 중요한 역할을 합니다.
반응형다음글이전글이전 글이 없습니다.댓글