할당되는 위치
참조 형식은 힙에 할당되고 가비지 컬렉터의 관리 대상이다.
값 형식은 스택 또는 인라인에서 할당되고 가비지 컬렉터의 관리 대상이 아니다.
이는 클래스(class) 객체는 힙(heap)에 할당되지만 구조체(struct) 객체는 스택(stack)에 할당됨 또한 의미한다.
※ 힙(heap) : 동적, 많은 메모리 영역을 가질 수 있다.
※ 스택(stack) : 정적, 비교적 적은 메모리 영역을 가진다.
값 형식은 스택이 해제되거나 포함된 형식이 할당 취소될 때 할당이 바로 취소된다.
따라서 참조 형식의 할당, 할당 취소보다 일반적으로 값 형식의 할당, 할당 취소가 저렴하다.
구조체 객체라도 힙에 할당되는 경우
배열의 할당 방식
참조 형식의 배열 요소는 힙에 있는 참조 형식 인스턴스에 대한 참조이고,
값 형식의 배열 요소는 실제 값 형식 인스턴스이다.
따라서 참조 형식 배열의 할당 및 할당 취소보다 값 형식 배열의 그것이 훨씬 저렴하다.
또한 값 형식 배열이 더 나은 지역성을 보인다.
메모리 사용
참조 형식은 캐스팅 될 때 Boxing, Unboxing이 일어나지 않는다.
값 형식은 참조 형식 또는 구현하는 인터페이스 중 하나로 캐스팅될 때 Boxing이 일어나고 값 형식으로 다시 캐스팅될 때 Unboxing이 일어난다.
이 과정에서 Boxing의 결과는 힙에 할당되고 가비지 수집되므로 Boxing, Unboxing이 너무 자주 일어나면 힙과 가비지 컬렉터에 악영향이 있을 수 있으며,
이는 결국 많은 계산과 자원(메모리)를 요구하게 된다.
따라서 참조 형식의 캐스팅이 값 형식의 캐스팅보다 저렴하다고 볼 수 있다.
할당(복사) 방식
참조 형식 할당은 참조를 복사한다.
값 형식 할당은 전체 값을 복제한다.
따라서 크기가 큰 객체의 경우 참조 형식의 할당이 값 형식의 할당보다 저렴하다.
참조 형식(클래스, class)의 할당은 얕은 복사,
값 형식(구조체, struct) 할당은 깊은 복사와 같다고 볼 수 있다.
전달 방식
참조 형식은 참조로 전달된다.
값 형식은 값으로 전달된다.
참조 형식의 인스턴스를 변경하면 인스턴스를 가리키는 모든 참조에 영향을 준다.
값 형식의 인스턴스는 전달될 때 복사되며, 따라서 값 형식의 인스턴스가 변경되어도 전달된 복사본에는 영향을 주지 않는다.
이는 사용자에게 혼동을 주기에 값 형식 인스턴스는 변경할 수 없어야 한다.
위와 같은 차이로부터, 어떤 경우에 구조체를 사용하는 것이 적절한지 판단이 가능하다.
일반적으로 대부분의 형식은 클래스여야 한다.
풍부한 객체 지향 기능을 지원
일반적인 적용 가능성
아래 같은 경우 구조체가 바람직하다.
아래 같은 특성이 없는 경우 구조체로 정의하는 것은 바람직하지 못하다.
기본 형식(int, double, float 등)과 유사한 단일 값을 나타낸다.
인스턴스 크기가 16바이트 미만이다.
변경할 수 없다.
자주 Boxing하지 않아도 된다. (자주 캐스팅하지 않아도 된다.)
인터페이스는 참조 형식과 값 형식 둘 다에서 구현할 수 있는 형식이다.