VisualStudio/C#

[C#] 값 형식(Value Types)과 참조 형식(Reference Types)

usingsystem 2022. 8. 10. 10:52
728x90

값 형식 : 변수가 값을 담는 데이터 형식.

참조 형식 : 변수가 값 대신 값이 있는 곳의 위치(참조)를 담는 데이터 형식.

 

이 둘을 이해하려면 두 가지 메모리 영역에 대해 알고있어야 한다.

바로 스택(Stack) 힙(Heap)이다.

 

이 메모리 영역 중 값 형식과 관련이 있는 것은 스택 메모리 영역이고,

참조 형식과 관련 있는 것은  메모리 영역이다.

 

1. 스택과 값 형식.

스택에 대해 이야기 해보자.

스택의 구조는 마치 책상 위에 쌓인 책이라고 생각하면 된다.

맨 밑에 있는 책을 읽고 싶다면, 위에 있는 책들을 모두 걷어낸 후에나 가능할 것이다.

스택 메모리도 이렇게 동작한다. 다음과 같은 코드를 작성했다고 하자.

{ // 코드 블록 시작
    int a = 10;
    int b = 20;
    int c = 30;
} // 코드 블록 끝

이렇게 선언된 세 변수 a,b,c는 차례대로 스택에 쌓였다가 코드 블록이 끝나면서 스택에서 걷혀 제거된다.

※ 블록을 닫는 괄호 "}"을 만나는 순간 스택에 있는 데이터들이 c,b,a의 순서대로 걷혀진다.

 

 

값 형식의 변수는 모두 이 스택에 저장된다.

다시 말해 코드 블록 안에서 생성된 모든 값 형식의 변수들은 중괄호 "}"을 만나면 메모리에서 제거된다.

 

2. 힙과 참조 형식

메모리 관리가 깔끔한 스택에 반해 힙은 데이터를 스스로 제거할 수 있는 매커니즘을 가지고 있지 않다.

대신 청소부 같은 존재를 고용하고 있는데, 그 청소부의 이름은 가비지 컬렉터(Garbage Collector)이다.

힙에 더 이상 사용하지 않는 객체가 있으면 그 객체를 쓰레기로 간주하고 수거해 가는 기능을 가지고 있다.

 

그렇다면 왜 굳이 가비지 컬렉터가 필요한 힙 영역을 사용하는 걸까?

스택에 쌓인 데이터들은 코드 블록이 사라지는 시점에서 함께 제거된다.

이것은 스택에 장점이기도 하지만, 동시에 한계이기도 하다.

 

코드 블록이 끝나는 시점과 상관없이 데이터를 유지하고 싶을 때는 스택의 구조가 발목을 잡는 요소가 된다.

 

그래서 또 다른 메모리 영역인 힙을 제공하는 것이다.

힙은 코드 블록이 종료되는 것과 관계없이 그 데이터를 게속 유지할 수 있다. 

그리고 이 데이터는 프로그래머가 더 이상 사용하지 않을 때가 됐을 때 가비지 컬렉터가 수거해 제거 한다.

 

참조 형식의 변수는 힙과 스택을 함께 사용하는데, 힙 영역에는 데이터를 저장하고, 스택 영역에는 데이터가 저장된

힙의 메모리의 주소를 저장한다. 그래서 참조 형식이라는 이름이 붙은 것이다.

 

참조 형식으로 변수를 선언해보자.

{
    object a = 10;
    object b = 20;
}
 

실제 값 10과 20은 힙 영역에 저장하고, a와 b는 값이 저장된 힙의 주소만 스택에 저장하게 된다.

블록이 끝난 시점에서 스택의 값은 사라진다. 하지만 힙에 남은 값을 사라지지 않는다.

 

힙의 남은 값은 더 이상 데이터를 참조하는 곳이 없을 때 가비지 컬렉터가 수거해 간다.

 

출처 - https://truecode.tistory.com/46



 

값 형식(Value Types)과 참조 형식(Reference Types)

C#에서는 메모리에 공간에 데이터를 할당하는 두 가지 방법이 있습니다.

값 형식(Value Types)은 스택(Stack) 공간에 데이터를 할당하며, 참조 형식(Reference Types)은 힙(Heap) 공간에 데이터를 할당합니다.

 

이번 포스팅에서는 값 형식과 참조형식에 대해 정리하였습니다.


스택(Stack)과 힙(Heap)

스택(Stack)

- 정적으로 메모리에 할당됩니다.

- 스택 영역에 있는 변수들은 선언된 함수를 빠져나가면 소멸됩니다.(= 블록을 닫는 괄호 "}"를 만나면 소멸됩니다.)

- FILO(First In Last Out) 또는 LIFO(Last In First Out)구조라고도 하는데, 스택 영역에 처음에 생성되었던 변수는 마지막에 소멸되고 마지막에 생성되었던 변수는 처음으로 소멸됩니다.

 

힙(Heap)

- 동적으로 메모리에 할당됩니다.

- 프로그래머가 원하는 시점에 동적으로 메모리를 할당하는데, 바로 이러한 유형의 변수들이 할당되는 영역이 힙 영역입니다.

- CLR의 가비지 컬렉터(Garbage Collector)가 힙 영역에 사용되지 않는 데이터들을 소멸시킵니다.


스택(Stack)과 값 형식(Value Type)

값 형식은 스택 메모리 공간에 데이터가 생성이 되며 값을 직접적으로 가지고 있습니다.

"{"를 시작으로 데이터가 순차적으로 생성이되며, "}"를 만나면 데이터가 순차적으로 소멸이 됩니다.

{                 // 1. 블록 시작
  int a = 100;   // 2. 변수 a 선언 및 초기화 
  int b = 200;   // 3. 변수 b 선언 및 초기화
}                // 4. 블록 종료

 

1. 블록 시작

블록 시작 시점에는 스택 영역에 아무것도 존재하지 않습니다.

 

 

 

2. 변수 a 선언 및 초기화

int a = 100; 코드가 실행이 되면서 변수 a가 스택 영역에 쌓이게 됩니다.

 

 

 

3. 변수 b 선언 및 초기화

int b = 200; 코드가 실행이 되면서 변수 b가 a위에 쌓이게 됩니다.

 

 

 

4. 블록 종료

블록을 종료하는 "}"를 만났으므로 블록 사이({ ~ })에 있는 변수들이 소멸됩니다.

① 스택은 마지막에 들어온 변수가 제일 먼저 소멸되므로 변수 b가 소멸됩니다.

② 변수 b 이전에 들어온 변수 a가 그다음으로 소멸됩니다.

③ 변수 a, b가 모두 소멸된 스택의 메모리 공간입니다.

 

 

 


힙(Heap)과 참조 형식(Refenect Type)

참조 형식은 힙 영역에 데이터가 저장이 되고 스택 영역에서는 데이터가 저장되어 있는 힙 영역의 메모리의 주소를 저장합니다.

스택 영역에 실제로 값을 가지고 있는게 아니라 힙 영역의 데이터를 참조하고 있으므로 "참조 형식"이라고 합니다.

{                  // 1. 블록 시작
  object a = 100;  // 2. 변수 a 생성 및 초기화
  object b = 200;  // 3. 변수 b 생성 및 초기화
}                 // 4. 블록 종료

 

1. 블록시작

블록 시작 시점에는 스택 영역과 힙 영역에는 아무것도 존재하지 않습니다.

 

 

 

2. 변수 a 생성 및 초기화

object는 참조 형식이므로 변수 a는 스택 영역에 생성되고 변수 a의 실제 값인 100은 힙 영역에 생성이됩니다.

스택 영역에 생성된 변수 a는 힙 영역에 생성된 100의 주소값인 1000을 가지고 있습니다.

변수 a는 주소값 1000으로 힙 영역에 접근하게 됩니다.

 

 

 

3. 변수 b 생성 및 초기화

스택 영역에 생성된 변수 b는 힙 영역에 생성된 200의 주소값을 가지고 있습니다.

 

 

 

4. 블록 종료

블록을 종료하는 "}"를 만났으므로 블록 사이({ ~ })에 있는 변수들이 소멸됩니다.

스택 영역에서는 변수가 소멸되었지만, 힙 영역은 가비지 콜렉터가 소거하므로 아직 소멸이 되지 않은 상태입니다.

 


값 형식(Value Types)과 참조 형식(Reference Types)의 주요 차이점

  1. 값 유형은 스택 메모리에 저장되고 참조 유형은 힙 메모리에 저장됩니다.
  2. 구조체, 문자열, 열거형을 제외한 모든 기본 데이터 유형은 값 유형의 Example입니다. Class, string, array, delegate, interface는 참조 유형의 Example입니다.
  3. 값 유형이 다른 값 유형에 복사되면 실제 값은 복사되지만 참조 유형이 다른 참조 유형에 복사되면 값의 참조 주소는 복사입니다.
  4. 값 유형은 0 으로 초기화 하고 참조 유형은 NULL 로 초기화 할 수 있습니다 .

출처: https://developer-talk.tistory.com/50 [평범한 직장인의 공부 정리:티스토리]

 

728x90