아래 글은 C# 문법 관련 개념 정리 및 작성자 공부를 위해 작성되었습니다.
📃 참고자료
* 위 두개의 링크를 참고해서 아래 글을 작성했습니다.
# 데이터 타입이란?
데이터를 저장하는 이유는 필요한 순간 읽고, 쓰고, 수정해서 저장
저장되는 데이터의 형식(타입)과 크기가 다르다 => 적절하게 잘 저장 (효율적)
테이터 타입의 종류
- 기본 데이터 타입(참고 자료 MSDN)
- 사용자정의 데이터타입
* CLR은 참조 타입(Reference Type)와 값 타입(Value Type)이라는 두 종류의 타입 체계를 지원한다.
# 값 형식(Value Type)
- 변수가 값을 담는 데이터 형식
- 값 형식과 관련이 있는 것은 스택(Stack) 메모리 영역
- primitive Type(int, float, bool, char와 같은 기본 데이터 타입)과 구조체가 이에 해당된다.
- 변수의 선언과 동시에 값을 할당할 수 있다.
- 이렇게 단일한 공간에 생성된 데이터는 직접적이며, 변수의 대입이나 매개변수로 데이터를 전달할 때
메모리 복사가 일어난다.
값 타입의 인스턴스는 그 자체가 하나의 필드이며 필드를 얻어내기 위해 역추적을 할 필요가 없고 GC의 관리 대상또한 아니다. C#에서 모든 클래스는 참조 타입이며 모든 구조체, 열거 타입은 값 타입 입니다. (System.Int32등도 구조체이다.)
# 참조 형식(Reference Type)
- 변수가 값 대신 값이 있는 곳의 위치(참조)를 담는 데이터 형식
- Class, String, Object(이것들과 더불어 배열은 그 구성요소의 형식과 상관없이 항상 참조형식이다.)
- 참조 타입을 사용하기 위해선 new 키워드를 통해 객체를 초기화한 후 힙에 할당된 메모리를
스택공간에서 참조해야 한다. - 객체를 지시하는 메모리는 필요로하는 메모리공간(힙)의 주소와 그것을 가리키는 참조 값(스택)으로
분리되어 저장된다. - 아직 수행되지 않은 데이터를 위해 예약어인 new 키워드를 사용해 객체를 초기화하여 인스턴스를 만들면
그 과정에서 시스템은 힙 공간에 필요한 만큼의 메모리 블록을 준비하여 스택에서 그 주소 정보를
참조할 수 있도록 해준다. - 여기서 참조 타입의 변수를 다른 곳에 대입하거나 매개변수로 데이터를 전달 할 때도 reference 자체만 복사되고
실제 참조로 가리키는 힙에 저장된 메모리는 동일하다.
참조 타입은 항상 관리되는 힙에 할당된다.
따라서 참조 타입을 사용할 때 마다 메모리의 할당이 발생하는데, 모든 타입이 참조 타입이라면 엄청난 성능 저하가 있을 것이다. 따라서 성능 향상을 목적으로, 단순하고 자주 사용되는 타입들을 위하여 경량화된 값 타입이 존재한다.
# 스택(Stack)
- 매우 빠른 액세스
- 변수를 명시 적으로 할당 해체 할 필요가 없습니다.
- 함수의 호출관 관계되는 지역변수와 매개변수가 저장되는 영역입니다.
- 공간은 CPU에 의해 효율적으로 관리되고 메모리는 단편화되지 않습니다.
- 지역 변수 만
- 스택 크기 제한(OS에 따라 다름)
- 변수의 크기를 조정할 수 없습니다.
- 스택의 구조는 마치 책상 위에 쌓인 책이라고 생각하면 됩니다.
값 형식은 코드 블록 안에서 생성된 모든 값 형식의 변수들을 중괄호 "}"을 만나면 메모리에서 제거됩니다.
# 힙(Heap)
- 변수는 전역 적으로 액세스 할 수 있습니다.
- 메모리 크기 제한이 없습니다.
- (상대적으로) 느린 액세스
- 효율적인 공간 사용을 보장하지 못하면 메모리 블록이 할당된 후 시간이 지남에 따라 메모리가
조각화되어 해제될 수 있습니다. - 메모리를 관리해야 합니다(변수를 할당하고 해제하는 책임이 있습니다)
메모리 관리가 깔끔한 스택에 반해 힙은 데이터를 스스로 제거할 수 있는 메커니즘을 가지고 있지 않다.
대신 청소부 같은 존재를 고용하고 있는데, 그 청소부의 이름은 가비지 컬렉터(Garbage Collector)이다.
힙에 더 이상 사용하지 않는 객체가 있으면 그 객체를 쓰레기로 간주하고 수거해 가는 기능을 가지고 있다.
가비지 컬렉터가 필요한 힙 영역을 사용하는 이유
스택에 쌓인 데이터들은 코드 블록이 사라지는 시점에서 함께 제거된다.
이것은 스택에 장점이기도 하지만, 동시에 한계이기도 하다.
코드 블록이 끝나는 시점과 상관없이 데이터를 유지하고 싶을 때는 스택의 구조가 발목을 잡는 요소가 된다.
그래서 또 다른 메모리 영역인 힙을 제공하는 것이다.
힙은 코드 블록이 종료되는 것과 관계없이 그 데이터를 계속 유지할 수 있다.
그리고 이 데이터는 프로그래머가 더 이상 사용하지 않을 때가 됐을 때 가비지 컬렉터가 수거해 제거 한다.
참조 형식의 변수는 힙과 스택을 함께 사용하는데, 힙 영역에는 데이터를 저장하고, 스택 영역에는 데이터가 저장된
힙의 메모리의 주소를 저장한다. 그래서 참조 형식이라는 이름이 붙은 것이다.
실제 값 10과 20은 힙 영역에 저장하고, a와 b는 값이 저장된 힙의 주소만 스택에 저장하게 된다.
블록이 끝난 시점에서 스택의 값은 사라진다. 하지만 힙에 남은 값을 사라지지 않는다.
* C#에서는 가비지 컬렉터가 처리
1번: 기본 && value
- byte, short, int, long, float, double, decimal, char, bool
2번: 사용자정의 && value
- struct, enum
3번: 기본 && Reference
- string, object
4번: 사용자정의 && Reference
- class, 배열
'프로그래밍언어 & 프레임워크 > C#' 카테고리의 다른 글
[토이프로젝트]UpDown 게임(컴퓨터의 랜덤 숫자 맞추기) (0) | 2021.08.05 |
---|---|
박싱(Boxing)과 언박싱(UnBoxing) (0) | 2021.08.04 |
어떻게 XAML과 C#코드가 연결되어 작동하는지 (0) | 2021.07.15 |
XAML 이란? (0) | 2021.07.13 |
WFP란? (0) | 2021.07.07 |