DNF LOVE

[OS] 메모리 구조, 프로그램 데이터가 적재되는 장소 본문

Computer Science/운영체제

[OS] 메모리 구조, 프로그램 데이터가 적재되는 장소

botho 2019. 10. 2. 23:50
반응형

컴퓨터 Process가 실행될 때 가장 중요한 부분은 어디일까?

어쩌면 당연한 이야기겠지만 Memory와 CPU이다.

우리는 프로그래밍 언어를 배우면서 정적변수, 지역변수 등을 나뉘며 이 둘은 다른 메모리 영역에 적재된다는 것을 스쳐가듯 배웠을 것이다.

그렇다면 각 데이터들은 어느 메모리에 적재되는 것일까?

 


이것은 어떤 OS 책을 읽나 기본적으로 보여주는 메모리 영역 그림이다.

Code, Data, Stack영역은 컴파일러가 알아서 메모리 영역을 결정해준다. 그러나 반대로 Heap영역은 개발자에 의해 프로그램 동작 시(RunTIme) 메모리에 데이터가 적재되는 특징을 갖고 있다.

각 영역은 어떤 데이터를 담고 특징을 갖고있는지 알아보도록 하자.


1. Code 영역 

 : 코드(=Text) 영역은 간단하게 실행할 프로그램의 코드가 저장되는 영역이다. 실제 연산을 하는 CPU는 이 코드 영역에 저장된 명령어를 하나씩 가져다가 처리를 한다. 즉, 코드 영역은 컴퓨터가 이해할 수 있는 기계어로 번역된 소스 코드가 올라간다.

2. DATA 영역

 : Data 영역은 프로그램의 전역 변수와 정적(Static) 변수가 저장되는 영역이다. 이는 프로그램이 시작과 동시에 데이터가 적재되며 프로그램이 종료되면 사라진다. 즉 전역변수와 정적변수는 프로그램이 종료될때까지 데이터가 계속 남아서 다른 함수에서도 사용할 수 있는 이유가 이때문이다.

3. Stack 영역 

 : Stack영역은 프로그램의 호출되는 함수의 지역 변수, 매개 변수가 저장되는 영역이다. Stack은 해당 함수가 시작, 호출되는 순간 적재되며, 함수가 종료될때 데이터는 사라진다.

Stack의 특징은 LIFO(List In First Out) 방식으로 가장 마지막으로 저장된 데이터가 가장 먼저 인출된다. 또한 Stack메모리의 특징은 다른 메모리 영역과 다르게 높은 메모리 주소에서 낮은 메모리 주소의 순서로 할당된다.

스택 영역에 저장되는 함수의 호출 정보를 Stack Frame이라고 하며, 프로그램에서 현재 실행 중인 함수에 대한 정보를 저장하는 스택 자료구조를 Call Stack이라고도 한다. Debug를 통해 Call Stack을 확인할 수 있다.

4. Heap 영역

 : Heap영역은 사용자에 의해 프로그램 진행 시 메모리를 사용할 수 있는 영역이다. 즉, 사용자가 원하는 시점에서 메모리를 할당하고(동적 할당) 소멸할 수 있도록 변수들이 할당되는 영역이다.

Stack에서 포인터 변수를 할당하고, 그 포인터가 가리키는 Heap영역의 임의의 공간부터 동적할당한 크기만큼 할당하여 사용한다. 

C 언어로 예시를 들자면

  • malloc()함수 : 메모리 공간을 힙 영역에 할당
  • free() 함수 : malloc()에 의해 할당된 메모리 공간을 소멸시킨다.
  • realloc() 함수 : 힙 영역 안에 이미 할당된 변수의 메모리 공간을 변경한다.

그러나 이렇게 할당된 Heap에서 오류로 인해 영역을 가리키는 포인터 반환이 안된 경우 또는 영역의 사용이 잘못된 경우 등의 이유로 힙 영역을 사용하지 못할때 [메모리 누수 현상 - Memory Leak]이라고 한다. 그래서 메모리를 사용하고 난 뒤 사용하지 않을 경우 메모리 반환을 꼭 해야 한다. 누수 현상으로 인한 값들을 Garbage라고 한다. C나 C++은 이 메모리 관리를 개발자가 해야하고, C#이나 JAVA같은경우 메모리 관리는 해당 언어의 가상 머신들이 관리한다. c#이나 JAVA는 그래서 Gabage Collection을 지원해준다.

4. Stack과 Heap사이에 빈 공간과 화살표 모양이 있는 이유 

 : 실제로 이들 사이에 메모리는 빈 공간을 지원한다. 이는 Stack과 Heap을 위한 여유공간이다.

Stack은 서브루틴이 시작되면서 메모리 공간이 필요해진 지역변수들을 적재하고, 서브루틴이 끝나면 소멸한다. 그렇기때문에 데이터 용량에 대한 불확실성을 가지기 때문에 밑에서부터 채워 올린다.

Heap역시 같은 이유에 의해 위에서부터 채워내려간다. 용량의 불확실성은 컴파일러가 적절하게 메모리 영역을 선택하여 적용한다.

  • Heap Overflow : Heap영역이 Stack영역을 침범
  • Stack Overflow : Stack영역이 Heap의 영역을 침범할때
반응형