2021
04.12

 

 

박싱과 언박싱을 이해하려면 값형식과 참조형식, 그리고 스택과 힙에 대한 이해부터 해야한다.

 

값형식 vs 참조형식

값형식System.ValueType을 상속받는다. (이 또한 System.Object를 상속받으니 참조형과 형변환이 가능하다) 

구조체, 열거형, 숫자(System.Int32) 는 값형식이다.

값형식은 스택에 할당되며, 스택은 성능이 빠르고 스코프가 끝나면 사라진다.

값형식은 주고받을 때, 복사가 일어난다.

 

참조형식은 System.Object를 상속받는다.

모든 클래스는 참조형식이다.

참조형식은 힙 영역에 할당되며, 힙은 메모리를 관리해야되기 때문에 조심히 다뤄야하는 영역이다. 

(GC가 있는 언어의 경우 사용이 끝났어도 GC가 수거할때까지 메모리에 상주한다)

참조형식은 주고받을 때, 주소만을 넘겨준다.

 

이 때문에 매개변수를 주고받을 때의 타입으로 구조체(값형식) vs 클래스(참조형식)을 비교하는 내용이 많다.  

 

참조형식은 왜 값형식보다 성능이 느릴까?

1. 스택 영역자체가 힙 영역보다 빠르다.

2. 참조형식은 인스턴스 할당시 인스턴스 주소(인스턴스가 할당된 메모리의 주소)외에도 두 개의 추가 필드가 할당된다.

동기화 블록인덱스(스레드 환경 접근관리), 타입객체포인터(타입에 대한 정보)

 

 

박싱(Boxing)

 - 값 형식을 참조 형식으로 변환하는 것.

 - 값을 스택 -> 힙으로 복사하고, 해당 메모리의 주소를 스택에 저장함.

  힙에 담기위해 System.Object라는 형식으로 감싼다고 해서 박싱이라고 부른다. 

 - 박싱은 일반적으로 암시적으로 진행되며, 명시적도 가능함.

object temp = 1;

 

언박싱(Unboxing)

 - 참조 형식을 값 형식으로 변환하는 것.

 - 데이터를 힙 -> 스택으로 복사한다.

 - 언박싱 시 타입이 다르거나, 작은 범위로 변환할 경우 오류가 발생한다.

object a = 20;
int b = (int)a;

 

박싱과 언박싱의 성능

 - 박싱은 단순 참조에 할당하는 것보다 20배까지 시간이 소모됨

 - 언박싱은 할당에 4배가량 소모됨. 

 - 박싱 -> 언박싱을 거치면서 값형식을 복사했던 힙메모리는 그대로 버려지기 때문에 가비지가 발생한다.

  (나중에 GC가 동작해야되니 성능상 불이익)

 

박싱과 언박싱은 많은 시간이 소모되니, 되도록 제네릭을 사용하여야 한다.

 

ArrayList, Stack, Queue 등의 기본형 자료구조들은 요소를 object로 사용한다.

때문에 데이터를 사용할 때 박싱과 언박싱 오버헤드가 발생한다.

 

List <T>, Stack <T>, Queue <T> 등의 제네릭 버전을 사용하면 이런 오버헤드를 방지할 수 있다.

 

 

 

COMMENT