📚박싱

object 타입은 참조 타입이기 때문에 힙에 데이터를 할당한다. 하지만 int, float 같은 타입은 값 타입이라 스택에 데이터를 할당한다.

1
2
int i = 1;
object a = i;

위 처럼 값 형식의 데이터를 object 타입 개체에 담을 수 있다. 이 경우 object 타입은 값 타입의 데이터를 힙에 할당하기 위해 박싱 기능을 제공한다. 쉽게 말해 박싱은 값 타입을 object 타입으로 변환하는 암시적인 기능이다. 값 타입을 박싱하면 힙에 개체 인스턴스가 할당되고 값이 새롭게 할당된 개체에 복사된다.

위 코드의 결과로 정수 1을 담고 있는 값 타입의 i 변수와 int 타입의 값을 참조하는 개체 참조 o가 스택에 만들어진다. 여기서 o가 참조하는 int 타입의 값은 변수 i에 할당된 값 타입의 값 1이 복사된 것이다.



📚언박싱

1
2
3
int i  = 1;
object a = i;
int j = (int)a;

a는 1이 박싱되어 저장된 힙을 참조하고 있다. j는 a가 참조하고 있는 메모리로부터 값을 복사한다. 힙에 있던 박싱된 값을 꺼내 값 타입 변수에 저장하는 과정을 언박싱이라고 한다. 쉽게 말하면 언박싱은 박싱과 다르게 object 타입을 값 타입으로 변환하는 명시적인 기능이다. 언박싱의 연산 과정은 아래와 같다.

  • 개체 인스턴스가 박싱된 값이 변환하려고 하는 값 타입인지 확인한다.
  • 인스턴스의 값을 값 타입 변수에 복사한다.

런타임에 값 타입의 언박싱이 성공하려면 언박싱되는 항목은 이전에 값 타입의 인스턴스를 박싱하여 생성된 개체에 대한 참조여야 한다. null을 언박싱하려고 시도하면 NullReferenceException이 발생하고 호환되지 않는 값 타입에 대한 참조를 언박싱하려고 하면 InvalidException이 발생한다.

null을 언박싱하려고 해서는 안되고, 박싱되어 있는 값의 타입과 언박싱하려는 타입이 다르면 오류가 난다고 이해하면 될 것 같다.



📚성능

박싱과 언박싱은 많은 계산 과정이 필요하다. 값 타입을 박싱할 때 힙에 새로운 개체를 할당하고 생성하는 것은 단순 참조 할당에 비해 느리다. 언박싱에 필요한 변환과정도 상당한 계산 과정이 필요하기 때문에 프로그램 성능에 안 좋은 영향을 줄 수 있을 것 같다.



Leave a comment