본문 바로가기

C# 코딩 기초

C# 기초 03.1 - 박싱(Boxing)과 언박싱(UnBoxing)

안녕하세요. "투명 나비" 입니다

 

지난 시간에는 컬렉션과 일반화 컬렉션을 배웠습니다. 

 

컬렉션은 모든 타입의 변수를 저장할 수 있고, 일반화 컬렉션은 선언된 타입의 변수만 저장할 수 있습니다

 

두 컬랙션의 차이 중 하나는 박싱(boxing) 문제에 대한 다른 접근입니다.

 

이번시간에는 코딩 보다 컴퓨터 내부에서 일어나는 일인 박싱(boxing)에 대해 알아보겠습니다.


먼저 박싱(boxing)에 대해 알아보기 전에 메모리를 저장하는 2가지 형식을 먼저 알아보겠습니다.

 

"값"과 "참조" 형식이 있습니다.

 - 값 형식(Value Type) : 실질적인 데이터의 값

   예) 기초 01 : 자료형(Data Type)에서 배웠던 정수형, 실수형, 문자형, 불린형입니다.

 

 - 참조 형식(Reference Type) : 값을 가지고 있는 "데이터의 주소"를 가지고 있는 값

   예) 기초 02: 배열(Array), 기초 03: 컬렉션(Collection)에서 배웠던, 배열, 배열리스트, 해시테이블 등 입니다. 

 

그리고 이것들은 2가지 공간에 저장됩니다.

 

값 형식(Value Type)을 저장하는 곳은 "스택(Stack) 메모리",

참조 형식(Referecne Type)을 저장하는 곳을 "힙(heap)메모리"이라고 합니다.

 

스택(Stack)메모리에 저장된 데이터가 힙(Heap)메모리로 저장되는 것이 박싱(Boxing)입니다

반대로, 힙(Heap)메모리에 저장된 데이터가 스텍(Stack)메모리로 저장되는 것이 언박싱(UnBoxing)입니다

 


박싱(Boxing)

위에서 설명 했듯이 데이터가 스택(Stack)메모리에서 힙(Heap)메모리로 가는 게 박싱(Boxing)이라고 설명 했습니다.

 

지금까지 배운 내용으로 어떻게 저장되는지 쉽게 머릿속에 떠오르지 않는데요.

 

아래에 예제를 보면서 조금 더 알아보겠습니다.

 

배열(Array) 또는 컬렉션(Collection)은 힙(Heap)메모리에 저장된다고 했습니다.

 

하지만 정확히 설명하면, 변수(주소)는 스택(Stack)에 그 변수가 가지고 있는 값 형식의 데이터는 힙(Heap)에 저장됩니다.

(물론, 배열 또는 컬렉션 기준입니다)

 

아래에 코드를 보시겠습니다.

ArrayList _ArrayList = new ArrayList();
_ArrayList.Add(33);    // 박싱(Boxing)

 

아래의 그림에서 조금 더 설명 하겠습니다.

Null의 뜻은 아무 값이나 참조를 가지고 있지 않다는 뜻입니다

 

변수_ArrayList(주소)는 스택(Stack)에 저장됩니다.

 

박싱(Boxing)이 발생합니다

_ArrayList.Add(33)는 먼저 정수 값 타입 "33"을 스택(Stack)에 저장합니다. 

그 다음 _ArrayList.Add() 함수를 실행합니다.

이때 스택(Stack)에 저장되어 있는 정수 값 타입 "33"이 변수 _ArrayList가 가르키고 힙(Heap)에 저장됩니다.


언박싱(UnBoxing)

박싱(Boxing)을 푼다고 언박싱(UnBoxing)이라고 합니다.

 

언박싱(UnBoxing)은 반대로 데이터가 힙(Heap)메모리에서 스택(Stack)메모리로 갑니다.

 

위에서 사용했던 코드 예제를 이어서 사용하겠습니다.

ArrayList _ArrayList = new ArrayList();
_ArrayList.Add(33);    // 박싱(Boxing)

int num = (int)_ArrayList[0]; // 언박싱(UnBoxing)

 

아래의 그림에서 조금 더 설명 하겠습니다.

언박싱(UnBoxing)이 발생합니다

 

int num = (int)_ArrayList[0]; 에 대해 설명하겠습니다.

 

먼저 _ArrayList[0] 힙(Heap)에 저장되어 있는 값을 가지고 있습니다.

(int)_ArrayList[0] : _ArrayList[0]값을 int 타입으로 형변환(추후 설명) 합니다.

마지막으로 형변환 된 정수 값 타입 "33"을 int 타입의 변수 num 값을 가르키는 스택(Stack)메모리에 넣습니다.

 

위 그림에서 알수 있듯, _ArrayList[0] 값은 그대로 있고, 복사된 값을 스택(Stack)에 넣습니다.

 


박싱(Boxing) 문제

이제 박싱(Boxing)과 언박싱(UnBoxing)을 배웠습니다. 

 

단순히 보기엔 이렇게 작동하는구나 하면 되지만, 성능적인 부분에 문제가 있습니다.

 

단순히 힙(Heap)에 값을 넣는것보다, 박싱(Boxing)을 통해서 힙(Heap)에 값을 넣으면 20배 까지 시간이 소모 됩니다.

또한, 단순히 스택(Stack)에 값을 넣는 것보다, 언박싱(UnBoxing)을 통해서 스택(Stack)에 값을 넣으면 4배 정도 시간이 소모 됩니다.

 

요즘 컴퓨터의 속도가 매우 빠르기 때문에, 1~2개 정도의 박싱과 언박싱 상관이 없습니다.

 

다만, 박싱(Boxing) 문제가 발생하는 배열(Array)과 컬렉션(Collection)은 다수의 데이터를 저장하기 위한 게 그 목적이고,

코드가 복잡해질 수록 더 많은 시간이 걸릴수 있습니다.

 

그럼으로 박싱(boxing)문제를 해결한 추후에 배울 일반화 컬렉션(Generalization Collection)을 사용하는 것을 권장합니다.


투명나비의 후기

 

박싱(Boxing)과 언박싱(UnBoxing)은 오래 전에 배웠던 내용으로

스텍(Stack)과 힙(Heap)의 이름만 기억하고 있던

저로서는 이번 포스팅을 통해 다시한번 그 개념을 확실하게 잡은것 같습니다.

 

그리고 아주 기초부터 알려주시는 다른 블로거 분들과 다르게,

저는 왜?(호기심), 어떤면에서 좋고, 나쁘고, 그럼 이건 뭐지? 라는 방식으로

하나씩 풀어나가고 있어, 제 글의 방향이 조금 생소하게 느껴지실 수 있습니다.

 

하지만, 아무런 연관 없는 기초를 배우고, 응용을 배우고를 반복하게 되면

아무런 생각없는 암기가 되어 버려서 일단 재미가 없습니다.

(암기에 약한 저는 기초만 4번째 다시 하는 중입니다......)

 

또한, 형변환(캐스팅)에 대한것은 추후에 설명하도록 하겠습니다.

 

역시나..... 왜?로 접근 하다보니, 알고있는 내용을 적는것 보다,

 

개인적인 호기심을 충족하는데 더욱 많은 시간을 써버렸네요...

 

예제의 그림도 7번 정도 수정 했어요ㅎㅎ

 

그럼 다음 포스팅때 만나뵙겠습니다.ㅎㅎ

 


참고

https://truecode.tistory.com/47

 

[C#] Object형식, 박싱과 언박싱.

1. Object형식 object형식은 "상속" 덕분에 어떤 데이터든지 다룰수 있는 데이터 형식이다. C#은 object가 모든 데이터를 다룰 수 있도록 하기 위해 특별 조치를 취했는데, 모든 데이터 형식이 자동으로 object형..

truecode.tistory.com

https://dybz.tistory.com/93?category=635756

 

[C#공부] Boxing & Unboxing

# Boxing이란? Boxing은 value type의 값을 object type으로 변환하는 것을 말한다. 닷넷 프레임워크에서 모든 타입은 object type의 상속을 받는다. 그래서 value type의 값을 좀 더 큰 영역으로 포장한다고 하..

dybz.tistory.com

http://www.mkexdev.net/Article/Content.aspx?parentCategoryID=1&categoryID=5&ID=671

 

MKEX Dev .NET

Microsoft. NET 을 시작하는 분들을 위한 강좌입니다. 주로 기초적인 내용과 때론 기본적인 내용을 다룹니다 [C# 기초강좌] 7. 박싱과 언박싱 작성자 : 박종명 최초 작성일 : 2010-07-02 (금요일) 최종 수정일 : 2010-07-02 (금요일) 조회 수 : 20717 회 “박싱/언박싱은 성능에 좋지 않습니다” 안녕하세요. 박종명입니다. 닷넷 일곱 번째 강좌를 진행하도록 하겠습니다 지난 강좌에서 C#의 자료형에 대해 알아 보았는데요. 자

www.mkexdev.net

https://hongjinhyeon.tistory.com/90

 

[C#] 박싱 과 언박싱 (Boxing & UnBoxing)

일반적인 프로그램을 만들면 이 개념에 대해서 몰라도 개발은 가능합니다. 그러나 사용되는 메모리가 많거나 관리가 필요하다면 필수적으로 알아야할 내용입니다. 1.박싱(Boxing) 값타입을 Object 형식 또는 이 값..

hongjinhyeon.tistory.com

https://grayt.tistory.com/87

 

[C#] 박싱/언박싱 (boxing/unboxing)

유니티 C# : 박싱과 언박싱 C#은 object가 모든 데이터를 다룰 수 있도록 하기 위해 모든 데이터 형식, 심지어 프로그래머들이 만드는 데이터 형식마저도 자동으로 object 형식을 상속 받는다. 즉, object는 모든..

grayt.tistory.com

https://jshzizon.tistory.com/entry/C-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-Boxing-Unboxing-%EB%B0%95%EC%8B%B1%EC%96%B8%EB%B0%95%EC%8B%B1

 

[C# 객체지향] Boxing & Unboxing 박싱/언박싱

오늘은 박싱과 언박싱에 대해서 알아보자. 박싱이란? 값타입을 참조타입으로 변환하는 것이다. 이게 무슨말이냐? 값 타입을 참조 타입으로 변환한다니.... 그전에 박싱/언박싱에 대해서 설명하기 위해서 구조체와..

jshzizon.tistory.com

https://debuglog.tistory.com/153

 

[Effective C#] 박싱과 언박싱을 최소화하라

[Effective C#] 박싱과 언박싱을 최소화하라 .NET Framework에서는 모든 타입의 최상위 타입을 참조타입인 System.Object로 정의하고 있다. object는 참조형식이 때문에 힙에 데이터를 할당한다. 반면, int나 doub..

debuglog.tistory.com