메모리 구조
메모리 구조
프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드(load)되어야 한다.
또한 프로그램이 실행되는 동안 CPU가 코드를 처리하기 위해서는, 메모리가 명령어와 데이터들을 저장해야 한다.
프로그램이 실행하게 되면 OS는 메모리(RAM)에 공간을 할당해준다.
<img width="700" alt="1" src="https://user-images.githubusercontent.com/65716445/205929196-7e1f59c0-3b2b-4db7-8e0c-9f9235af7ccd.png">
> 프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간
<img width="390" alt="1" src="https://user-images.githubusercontent.com/65716445/205929202-3c6f16ca-a42a-444c-afcb-ddc7d9db4b92.png">
코드(code) 영역
---
- 실행할 프로그램의 코드(=우리가 작성한 소스코드)가 저장되는 영역
- 텍스트(text) 영역이라고도 한다.
- CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.
- 프로그램이 시작하고 종료될 때까지 메모리에 계속 남아있는다.
데이터(data) 영역
---
- 전역 변수와 정적(static) 변수가 할당되는 영역
- 숫자나 문자열 값인 리터럴도 저장된다.
- 프로그램의 시작과 동시에 할당되며, 프로그램이 종료되면 메모리에서 소멸한다.
힙(heap) 영역
---
- 동적으로 할당된 변수가 할당되는 영역(Dynamic Memory Allocation)
- 프로그래머가 직접 공간을 할당, 해제하는 메모리 공간
- 영역 중 유일하게 런타임 시 크기가 결정된다.
- 선입선출(FIFO) 구조로, 가장 먼저 들어온 데이터가 가장 먼저 인출된다.
- 힙 영역이 메모리의 낮은 주소에서 높은 주소의 방향으로 할당 되기 때문
<img width="400" alt="1" src="https://user-images.githubusercontent.com/65716445/205929204-e56e5c2b-fbee-44b1-9746-d0c07a83cf7f.png">
스택(stack) 영역
---
- 프로그램이 자동으로 사용하는 임시 메모리 영역
- 함수 호출 시 생성되는 지역 변수와 매개 변수가 저장되는 영역으로, 함수 호출이 완료되면 저장된 메모리도 해제된다.
- 스택 영역은 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출한다. → 후입선출(LIFO) 구조
- 스택 영역이 메모리의 높은 주소에서 낮은 주소의 방향으로 할당 되기 때문
오버 플로우
---
<img width="400" alt="1" src="https://user-images.githubusercontent.com/65716445/205929206-a9b8fd77-1c59-427b-8eb3-2310c8989d2b.png">
- 오버 플로우란 영어로 넘쳐흐른다는 뜻
- 한정된 메모리 공간이 부족하여 메모리 안에 있는 데이터가 넘쳐 흐르는 현상
오버 플로우의 종류 중에 힙 오버 플로우와 스택 오버 플로우가 있다.
힙은 메모리 위쪽 주소부터 할당되고, 스택은 메모리 아래쪽 주소부터 할당되기 때문에 각 영역이 상대 공간을 침범하는 일이 발생할 수 있다.
이때 힙이 스택을 침범하는 경우를 힙 오버 플로우라 하고, 스택이 힙을 침범하는 경우를 스택 오버 플로우라고 한다.
스택과 힙을 나눠놓은 이유
---
스택
스택은 매우 빠르게 접근과 할당이 가능하며 메모리에 낭비되는 공간 없이 사용가능하다.
스택의 의미대로 그냥 차례대로 쌓는 연속적인 메모리 영역이기 때문이다.
하지만 용량이 적어서 쓰기 힘들 수 있다.
힙
힙은 사용자가 따로 할당, 관리를 해서 사용해야하는 공간으로 스택보다는 느리게 할당된다.
용량은 크지만 단편화의 위험성을 가지고 있다.
\*단편화: 기억 장치의 빈 공간 또는 자료가 여러 개의 조각으로 나뉘는 현상
하지만 크기를 먼저 설정해주는 스택영역에서 보다 유연함을 가지고 있다.
반면에, 제대로 반환하지 않으면 Memory Leak(메모리 누수)이 일어나 메모리에 손해를 볼 수 있다.
그렇다면 모든 영역을 단편화가 없는 스택으로 구현하면 안되나?
안된다!
스택의 특성상 데이터의 접근할 수 있는 부분은 top 뿐이다.
스택에 활성레코드가 저장될 수 있는 이유이자, 스택 자료구조를 적용할 수 있는 이유이며, 함수가 실행 중일때만 접근 가능한 공간이다.
따라서 중간에 접근하려고 해도 불가능한 경우가 많다.
→ 힙에 할당을 하게 되면 포인터로 해당 데이터에 접근이 가능하다.
즉,
프로그램 상에서 얼마나 메모리가 필요할 지 모르는 상태이고,
미리 모두 할당해놓는 것은 쓰이지 않을 메모리까지 할당되어있는 비효율적인 상태에 놓일 수 있으므로
스택, 힙으로 나누어 할당을 하는 것이라고 할 수 있다.
> 참고자료 > [1](https://luv-n-interest.tistory.com/1046) > [2](https://lxxyeon.tistory.com/70) > [3](https://all-young.tistory.com/17)