🔥 메모리 구조
프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간
- 프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드(load)되어야 한다.
- 또한 프로그램이 실행되는 동안 CPU가 코드를 처리하기 위해서는, 메모리가 명령어와 데이터들을 저장해야 한다.
- 프로그램이 실행하게 되면 OS는 메모리(RAM)에 공간을 할당해준다.
🔆 코드(code) 영역
- 실행할 프로그램의 코드(=우리가 작성한 소스코드)가 저장되는 영역
- 텍스트(text) 영역이라고도 한다.
- CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.
- 프로그램이 시작하고 종료될 때까지 메모리에 계속 남아있는다.
🔆 데이터(data) 영역
- 전역 변수와 정적(static) 변수가 할당되는 영역
- 숫자나 문자열 값인 리터럴도 저장된다.
- 프로그램의 시작과 동시에 할당되며, 프로그램이 종료되면 메모리에서 소멸한다.
🔆 힙(heap) 영역
- 동적으로 할당된 변수가 할당되는 영역(Dynamic Memory Allocation)
- 프로그래머가 직접 공간을 할당, 해제하는 메모리 공간
- 영역 중 유일하게 런타임 시 크기가 결정된다.
- 선입선출(FIFO) 구조로, 가장 먼저 들어온 데이터가 가장 먼저 인출된다.
- 힙 영역이 메모리의 낮은 주소에서 높은 주소의 방향으로 할당
되기 때문이다.
🔆 스택(stack) 영역
- 프로그램이 자동으로 사용하는 임시 메모리 영역
- 함수 호출 시 생성되는 지역 변수와 매개 변수가 저장되는 영역으로, 함수 호출이 완료되면 저장된 메모리도 해제된다.
- 스택 영역은 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출한다. → 후입선출(LIFO) 구조
- 스택 영역이 메모리의 높은 주소에서 낮은 주소의 방향으로 할당 되기 때문
간단 요약
App :
Code - 어플을 구동하기 위한 개발자 작성 코드
Data - 변수
Stack - 함수를 호출하는 실행순서
Heap - 복잡한 데이터, 객체
💡 오버 플로우
- 오버 플로우란 영어로 넘쳐흐른다는 뜻
- 한정된 메모리 공간이 부족하여 메모리 안에 있는 데이터가 넘쳐 흐르는 현상
오버 플로우의 종류 중에 힙 오버 플로우와 스택 오버 플로우가 있다.
힙은 메모리 위쪽 주소부터 할당되고, 스택은 메모리 아래쪽 주소부터 할당되기 때문에 각 영역이 상대 공간을 침범하는 일이 발생할 수 있다.
이때 힙이 스택을 침범하는 경우를 힙 오버 플로우라 하고, 스택이 힙을 침범하는 경우를 스택 오버 플로우라고 한다.
🔆 스택과 힙을 나눠놓은 이유
💦 스택
- 스택은 매우 빠르게 접근과 할당이 가능하며 메모리에 낭비되는 공간 없이 사용가능하다.
- 스택의 의미대로 그냥 차례대로 쌓는 연속적인 메모리 영역이기 때문이다.
- 하지만 용량이 적어서 쓰기 힘들 수 있다.
💦 힙
- 힙은 사용자가 따로 할당, 관리를 해서 사용해야하는 공간으로 스택보다는 느리게 할당된다.
- 용량은 크지만 단편화의 위험성을 가지고 있다.
*단편화: 기억 장치의 빈 공간 또는 자료가 여러 개의 조각으로 나뉘는 현상
- 하지만 크기를 먼저 설정해주는 스택영역에서 보다 유연함을 가지고 있다.
- 반면에, 제대로 반환하지 않으면 Memory Leak(메모리 누수)이 일어나 메모리에 손해를 볼 수 있다.
🤔 그렇다면 모든 영역을 단편화가 없는 스택으로 구현하면 안되나?
🙅♀️안된다!
-
스택의 특성상 데이터의 접근할 수 있는 부분은 top 뿐이다.
-
스택에 활성레코드가 저장될 수 있는 이유이자, 스택 자료구조를 적용할 수 있는 이유이며, 함수가 실행 중일때만 접근 가능한 공간이다.
-
따라서 중간에 접근하려고 해도 불가능한 경우가 많다.
→ 힙에 할당을 하게 되면 포인터로 해당 데이터에 접근이 가능하다.
✨ 즉,
프로그램 상에서 얼마나 메모리가 필요할 지 모르는 상태이고,
미리 모두 할당해놓는 것은 쓰이지 않을 메모리까지 할당되어있는 비효율적인 상태에 놓일 수 있으므로
스택, 힙으로 나누어 할당을 하는 것이라고 할 수 있다.
참고 자료
💘 🌱 👏