안녕하세요. "투명 나비" 입니다
지난 시간에는 컬렉션과 일반화 컬렉션을 배웠습니다.
컬렉션은 모든 타입의 변수를 저장할 수 있고, 일반화 컬렉션은 선언된 타입의 변수만 저장할 수 있습니다
두 컬랙션의 차이 중 하나는 박싱(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)
아래의 그림에서 조금 더 설명 하겠습니다.
변수_ArrayList(주소)는 스택(Stack)에 저장됩니다.
_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)
아래의 그림에서 조금 더 설명 하겠습니다.
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
https://dybz.tistory.com/93?category=635756
http://www.mkexdev.net/Article/Content.aspx?parentCategoryID=1&categoryID=5&ID=671
https://hongjinhyeon.tistory.com/90
https://debuglog.tistory.com/153
'C# 코딩 기초' 카테고리의 다른 글
C# 기초 블로그 업데이트 순서 (0) | 2024.04.05 |
---|---|
C# 기초 03.2 - 스택(Stack)과 힙(Heap) (0) | 2020.01.01 |
C# 기초 04 - 일반화 컬렉션(Generalization Collection) (0) | 2019.12.07 |
C# 기초 03 - 컬렉션(Collection) (0) | 2019.11.30 |
C# 기초 02 - 배열(Array) (1) | 2019.11.24 |