[CS] 값타입과 참조타입 (Value Type & Reference Type)
값 타입과 참조 타입은 메모리 저장 방식과 동작 방식이 다른 두 가지 데이터 유형.
1. 값 타입 (Value Type)
1) 개념
- 스택(Stack) 메모리에 저장됨.
- 변수를 할당하면 값 자체가 저장됨.
- 변수를 다른 변수에 대입하면 값이 복사됨(독립적인 메모리 공간을 가짐)
- 메모리에서 빠르게 할당 및 해제 됨(GC의 영향을 덜 받음)
int a = 10;
int b = a; // 'a'의 값이 'b'로 복사됨
b = 20;
Console.WriteLine(a); // 10 (a의 값은 영향을 받지 않음)
Console.WriteLine(b); // 20
▶ a를 b에 대입해도 별개의 메모리 공간을 가지므로 b를 변경해도 a의 값이 변경되지 않음
2) 특징
(1) 값이 직접 저장됨.
- 변수를 복사해도 독립적인 데이터가 생성됨(값을 공유하지 않음)
(2) 빠른 접근 속도
- 스택(Stack)에 저장되므로 힙(Heap)보다 빠르게 접근 가능
(3) 일반적으로 크기가 작음
- 메모리 사용이 효율적이며 가비지컬렉터(GC)의 영향을 받지 않음
3) 값 타입의 종류
(1) 기본 데이터 타입
- int, float, double, char, bool 등
(2) 구조체(struct)
(3) 열거형(enum)
2. 참조 타입 (Reference Type)
1) 개념
- 힙(Heap) 메모리에 저장됨.
- 변수를 할당하면 실제 데이터가 아니라 데이터의 주소가 저장됨
- 변수를 다른 변수에 대입하면 주소가 복사됨(동일한 객체를 가리킴)
- 가비지컬렉터(GC)에 의해 메모리 관리됨
class Person {
public string Name;
}
Person p1 = new Person();
p1.Name = "Alice";
Person p2 = p1; // 참조(주소) 복사
p2.Name = "Bob";
Console.WriteLine(p1.Name); // "Bob"
Console.WriteLine(p2.Name); // "Bob"
▶ p1과 p2는 같은 객체를 참조하므로 p2.Name 을 변경하면 p1.Name도 변경됨
2) 특징
(1) 데이터가 힙에 저장됨
- 참조 변수는 객체의 주소를 가지고 있음
(2) 변수 간 대입 시 주소를 공유
- 같은 객체를 참조하면, 한 변수를 변경하면 다른 변수도 영향을 받음
(3) 가비지컬렉터의 관리 대상
- 객체가 더 이상 참조되지 않으면 자동으로 메모리에서 해제됨
3) 참조 타입의 종류
(1) 클래스 (Class)
- string, List<T>, object
(2) 인터페이스 (Interface)
(3) 배열(Array)
(4) 델리게이트 (delegate)
- 메서드를 참조하는 타입
3. 값 타입 VS 참조 타입 비교
비교 항목 | 값 타입(Value Type) | 참조 타입(Reference Type) |
저장위치 | 스택 메모리 | 힙 메모리 |
메모리 저장 방식 | 값 자체 저장 | 데이터 주소(참조) 저장 |
변수 간 복사 | 새로운 값이 복사됨(독립적) | 주소가 복사됨(공유됨) |
성능 | 빠름(메모리 접근이 빠름) | 상대적으로 느림(GC 영향) |
GC 영향 | 없음 | 있음 |
예시 | int, float, char, bool, struct | class, array, string, List<T> |
+ struct VS class 선택 기준
(1) struct
- 크기가 작은 데이터 구조
- 변경할 필요가 없는 불변(immutable) 데이터
- 성능 최적화가 중요한 경우(GC 영향을 줄이기 위해)
(2) class
- 크기가 큰 데이터 구조
- 객체를 여러 곳에서 공유해야 하는 경우
- 메서드와 데이터를 함께 포함해야 하는 경우
+ ref 키워드
: ref 키워드를 사용하면 값 타입을 참조 방식으로 전달 가능 (C#)
void Update(ref int x)
{ x += 10; }
int num = 5;
Update(ref num);
Console.WriteLine(num); // 15 (원본 값 변경됨)