Programming/.NET

컴퓨터(Computer)가 프로그램(Program)을 실행하려면 우선 프로그램의 코드(Code)와 프로그램에서 사용하는 데이터를 메모리(Memory)에 적재해야 합니다. 그리고 메모리에 적재된 프로그램코드를 CPU가 하나씩 실행함으로서 결과적으로 컴퓨터가 프로그램을 동작시키는 것입니다.

 

이때 데이터를 저장하기 위한 메모리는 용도에 따라 힙과 스택으로 분류될 수 있습니다.

 

1. 스택(Stack)

 

프로그램이 실행되는것 자체를 하나의 프로세스(Process)라고 볼 수 있습니다. 그런데 프로세스가 시작되면 하나의 주 스레드(Thread)가 실행되며 실제 프로그램의 동작처리는 이 스레드가 담당하게 됩니다. 하나의 프로세스는 여러개의 스레드를 실행시킬 수 있고 이 스레드가 모두 실행이 종료되어야 비로소 프로세스도 함께 종료됩니다.

 

스택은 스레드마다 할당되는 메모리로서 최대 1MB의 크기를 가집니다. 스레드에는 주로 프로그램 내에서 정의된 메서드의 실행을 위한 데이터를 담고 있으며 메서드 호출시의 인자값, 메서드내부의 지역변수 데이터, 메서드 실행 후 주메서드에서 실행을 이어갈 주소등이 여기에 해당합니다. 스레드가 메서드의 실행을 종료하면 그때서야 비로소 점유했던 메모리를 다시 회수합니다. 메모리를 회수한다고 해서 최초 할당된 1MB의 용량이 줄어드는것은 아니고 단지 다른 메서드의 실행을 위한 확보차원입니다.

 

1MB의 스택공간은 매우부족해 보이지만 보통 메서드의 호출을 위해서는 충분한 용량이며 1MB의 용량이 모두 채워져 더이상 메모리를 할당할 수 없는 상태를 '스택 오버플로우'라고 하는데 이러한 경우는 주로 프로그램내에서 자기자신을 호출하는 재귀호출시에 많이 나타나며 이때는 프로그램이 강제로 종료됩니다.

 

2. 힙(Heap)

 

프로그램에서 new를 통해 참조형 객체를 생성하면 이 데이터는 스택과 힙공간에 할당됩니다. 이때 힙에는 실제 데이터가 들어가지만 스택에는 힙에 할당된 메모리의 주소값이 들어가게 됩니다. C#에서 new로 할당된 힙메모리는 따로 해제하는 방법을 두지 않는데 이는 GC(Garbage Collector)가 알아서 힙메모리를 할당하고 해제하기 때문입니다.

 

값형식은 힙이 아닌 스택에 할당됩니다. 다만 값형식이 참조형식으로 바뀌게 되면 힙에 할당될 수 있는데 이런 과정을 박싱(Boxing)이라고 하며 그 반대를 언박싱(Unboxing)이라고 합니다.

 

예를 들어

 

static void Main(string[] args)
{
    int i = 10;

    object o = i;

    int j = (int)o;
}

 

정수형 변수값이 object에 대입되는 경우 object형은 참조형식이기에 메모리 주소는 스택에, 실제 데이터는 힙에 들어가는 박싱이 이루어지고, 다시 object형 변수가 정수형 변수에 대입될때는 힙메모리에 있는 데이터가 스택으로 이동하는 언박싱이 이루어지는 것입니다. 참고로 박싱은 GC의 개입을 필요로 하므로 성능에 좋지않습니다.

'Programming > .NET' 카테고리의 다른 글

정규식(Regular)  (0) 2019.06.20
힙과 스택  (0) 2019.06.11
[C#] StringBuilder  (0) 2019.05.28
[C#] Stopwatch  (0) 2019.05.09
가비지 수집기 : GC (Garbage Collector)  (0) 2019.04.30
[C#] null 조건  (0) 2019.04.16
0 0