메모리
메모리에 값이 저장되는 과정을 살펴보자.
우선 C#의 모든 Type은 Object를 상속받는다.
1) 값 형식
값 형식이란, 변수가 값을 담는 형식을 뜻한다.
기본적으로 스택 메모리에 할당된다.
2) 참조 형식
참조 형식이란, 변수가 값 대신 값의 위치(참조)를 담는 형식을 뜻한다.
힙 메모리 영역에 할당된다.
참고로 참조 형식은 null 할당이 가능하다.
메모리 할당
코드와 데이터 영역은 컴파일 시 크기가 지정되고,
힙과 스택 영역은 런타임 시 크기가 지정된다.
박싱과 언박싱
1) 박싱: 값 타입 객체를 참조 타입으로 변환
2) 언박싱: 참조 타입을 값 타입으로 변환
[유니티 C#] 박싱과 언박싱
Boxing, Unboxing
velog.io
이는 단순 참조 할당보다 최대 20배 더 오래 걸릴 수 있으며,
언박싱할 때 캐스팅 프로세스는 할당보다 4배 더 오래 걸릴 수 있다.
박싱
int i = 123;
object obj = i; // 암시적 박싱
object obj = (object)i; // 명시적 박싱
언박싱
int i = 123; // 갑 형식
object obj = i; // 암시적 박싱
int j = (int)obj; // 명시적 언박싱
코드 실습: 박싱과 언박싱
queue1은 모든 형식의 객체(object)를 담을 수 있는 큐입니다.
queue2는 string 형식의 객체만을 담을 수 있는 큐입니다.
1) 1번과 2번의 차이
queue1에 10이라는 int형 객체를 담았습니다. 그러나 queue1은 object 형 객체를 담는 큐이므로,
int형인 10이 object형으로 "박싱"됩니다.
스택 메모리에 참조값이 저장되고, 해당 주소의 힙 메모리에 가보면 10이 저장되어 있습니다.
queue2에는 "10"이라는 string형 객체를 담았습니다. queue2는 string 형 객체를 담는 큐이므로,
string형인 "10"이 힙 메모리에 저장됩니다. 그러나 이것은 "박싱"은 아닙니다.
박싱은 값 형식을 참조 형식으로 변환하는 것이기 때문입니다.
여기서는 참조 형식을 참조 형식에 담았으므로 박싱이 아닙니다.
https://pyowatermelon.tistory.com/81
4/18 : TIL | Object, 참조/값 형식, 박싱 - 언박싱의 개념
Object C#의 데이터 형식은 크게 4가지이다. 숫자, 논리, 문자열, 오브젝트 형식이 있다. 이 중 특별하게 Object 형식은 영단어 뜻 '객체' 그대로 어떤 데이터든지 다룰 수 있는 형식이다. Object가 특별
pyowatermelon.tistory.com
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestConsoleApp
{
class Program
{
static void Main(string[] args)
{
Queue queue1 = new Queue(); //큐, object 값을 담음
Queue<string> queue2 = new Queue<string>(); //제네릭 큐, string 값을 담음
//1
queue1.Enqueue(10); //박싱
//2
queue2.Enqueue("10"); //박싱 X
//3
var result1 = queue1.Dequeue(); //언박싱 X
//int num = result1; // 언박싱 X, 오류 발생
int num = (int)result1; // 언박싱
//4
var result2 = queue2.Dequeue(); //언박싱 X
Console.WriteLine(result1.GetType().Name);
Console.WriteLine(result2.GetType().Name);
Console.ReadLine();
}
}
}
object 형식을 int 형식으로 변환할 수 없다는 오류 메시지가 뜬다. 그렇다면
답은 이렇게 된다.
2) 3번과 4번의 차이
queue1에 담긴 객체를 꺼냅니다. 힙 메모리에 저장되어있던 object 형식인 10을 꺼내 result에 담습니다.
이때 result 또한 object 형식으로, var가 10의 형식을 파악하여 object형으로 힙 메모리에 저장합니다.
그러나 이것은 언박싱은 아닙니다. 참조 형식이었던 object가 참조형식인 object가 된 것이기 때문입니다.
이것이 언박싱이 되려면 코드를
var result = (int)Queue1.Dequeue();
위와 같이 수정해야 할 것입니다.
다음으로 queue2에 담긴 객체를 꺼냅니다. 힙 메모리에 저장되어있던 "10"을 꺼내 result에 담습니다.
이때 result는 참조 형식으로, var가 "10"의 형식을 파악하여 string 형으로 힙 메모리에 저장합니다.
그러나 이것은 참조 형식을 값 형식으로 변환하는 언박싱은 아닙니다. 참조 형식이 참조 형식이 된 것이기 때문입니다.
'C# > 이것이 C#이다' 카테고리의 다른 글
7장. 클래스: this 키워드, this() 생성자, 접근 한정자, static 변수, 구조체 (0) | 2023.04.19 |
---|---|
6장. 확장메소드, this와 ref, out, params 등 키워드, string.Empty (0) | 2023.04.19 |
4장. 데이터의 흐름 제어: 분기문, 반복문 (0) | 2023.04.18 |
3장. 데이터 보관하기: 자료형, 배열, 형 변환, 형식 확인, 입출력 (0) | 2023.04.18 |
2장. C#의 클래스와 네임스페이스 (0) | 2023.04.18 |