사용자가 프로그램의 실행을 요청하면 운영체제(OS)는 보조기억장치(HDD, SDD 등)로부터 해당 프로그램의 정보를 읽어 주기억장치(메모리)에 로드한다. 그리고 CPU는 프로그램 코드로 메모리를 관리하고 메모리에 로드된 명령문을 실행한다.
메모리는 크게 커널(Kernel) 영역과 유저(User) 영역으로 나뉘며, 커널 영역에는 운영체제가 적재된다. 따라서 사용자가 실행하는 프로그램 등은 일반 프로세스로서 유저 영역에 적재된다. 그리고 유저 영역의 프로세스 메모리 구조는 다시 몇 가지 구조로 나뉘어진다.
프로세스의 주소 공간은 크게 Code, data, heap, stack 네 가지 영역으로 이루어져 있으며, 순서대로 낮은 메모리 주소부터 높은 메모리 주소 순으로 배정된다. 단, Stack 영역은 유일하게 높은 메모리 주소부터 낮은 메모리 주소 순으로 쌓여 나간다.
스택 영역 | 힙 영역 | |
---|---|---|
장점 | 데이터 액세스가 빠르다. 변수를 사용자가 관리하지 않아도 된다. 하나의 명령으로 메모리 조작과 어드레스 조작이 가능하다. OS가 직접 메모리를 관리하기 때문에 메모리 단편화에 대한 걱정이 없다. | 변수를 전역적으로 액세스할 수 있다. 메모리 크기에 제한이 없다. 객체의 개수나 크기를 알 수 없어도 사용 가능하다. |
단점 | 지역변수만 저장된다. 스택 크기가 제한되어 있다. 변수의 크기를 조정할 수 없다. | 상대적으로 데이터 액세스가 느리다. 메모리를 직접 관리해야 한다. |
힙 영역과 스택 영역은 사실상 동일한 공간을 사용하며, 따라서 스택 영역이 클수록 힙 영역이 작아지고, 반대로 힙 영역이 커지면 스택 영역이 작아진다.
이때 스택 영역은 높은 주소에서 낮은 주소 순으로, 힙 영역은 낮은 주소에서 높은 주소 순으로 주소가 할당되므로 자신의 영역이 상대의 영역을 침범하는 경우가 발생할 수도 있다. 이를 각각 스택 오버플로우, 힙 오버플로우라고 한다.