과제를 하다 보면 메모리에 관련해서 생각해야 될 부분이 많다. 한정된 자원 안에서 효율적으로 프로그램을 실행하려면 항상 메모리를 염두에 두어야 한다. 그렇다면 메모리란 무엇이고, 내가 작성한 파일, 코드, 등 모든 것들은 어디에 어떻게 저장되는 것일까?

먼저 메모리가 무엇인지 생각해 보아야 한다. 메모리는 무엇이고 왜 필요한 것일까? 프로그램이 실행되려면 로드(load) 되어야 한다. 로드는 프로그램의 구성요소들을 저장한다는 뜻인데 이때 저장할 공간이 필요할 것이다. 이 저장 공간을 메모리라고 한다.

우리가 보통 ‘메모리에 저장된다’고 할 때의 메모리는 주기억장치를 의미하며 메모리는 크게 code, data, heap, stack 4가지 영역으로 나누어진다. 검색을 하다 메모리의 구조와 위치를 한눈에 보기 좋은 그림이 있어 가져왔다.

메모리의 공간의 구조.png

위 그림과 같이 메모리의 영역은 Code → Data → Heap → Stack으로 나뉘어진다.

Code 영역 사용자가 작성한 코드가 저장되는 영역으로 컴파일 된 후 기계어 형태로 저장되어 있다. Code 영역은 물리적으로 ROM에 위치해있다.

Data 영역은 전역변수(global variable), 정적 변수(static variable)가 저장되는 영역이며, 프로그램의 시작과 함께 main 함수가 호출되기 전 할당되며, 프로그램이 종료되면 소멸한다. 위 그림을 보면 ROM에도 Data영역이 있고, RAM에도 데이터 영역이 있다. 또 BSS라는 소개하지 않은 영역도 있다. 데이터영역은 BSS 영역과 Data 영역으로 나뉜다. Data 영역에는 초기화된 변수들이 저장되며, 초기화된 데이터는 ROM의 Data영영에 저장되는데 ROM은 read only memory라서 수정이 불가능하며 계속 초깃값만을 가지고 있을 수 밖에 없다. 그래서 Data 영역을 RAM에 복사하여 프로그램이 실행될 시 변경되는 값을 저장할 수 있도록 한다. BSS 영역은 어떤 역할을 할까? 아직 초기화되지 않은 데이터들까지 ROM에 저장하려면 더 큰 공간이 필요하기 때문에 BSS(Block Started by Symbol) 영역에 초기화되지 않은 전역 데이터를 저장하는 영역이다.

Heap 영역은 프로그램이 실행되는 동안 동적으로 할당하는 데이터가 저장되는 영역이다. 사용자가 직접 관리하는 영역으로 C언어에서 malloc, free를 하면 이 영역에 저장된다.

Stack 영역은 함수 호출 시 생성되는 지역변수와 매개변수가 저장된다. 함수 호출 시 할당되며 실행이 끝나면 메모리에서 해제된다. Stack 영역과 Heap 영역은 같은 공간을 나눠서 사용한다. 그래서 한 영역이 커지면 다른 한쪽은 작아진다. 한 쪽의 저장 공간이 부족하면 상대의 영역을 침범하게 되는데 이를 스택 오버플로우, 힙 오버플로우 라고 부른다.

과제를 하면서 단순히 메모리 누수가 난다, 메모리에 저장된다는 말이 추상적으로 느껴져 어려웠는데 메모리의 구조와 내가 선언한 변수가 어떤 공간에 어떻게 저장될지 이해하고 있으면 메모리에 관련된 문제를 쉽게 풀 수 있을 것이다.