📒 메모리 구조
📌 프로그램 동작 원리
- 사용자가 운영체제를 통해 프로그램 실행을 요청한다.
- 하드디스크에 저장되어 있던 프로그램을 작동시키기 위해 메모리의 프로그램 코드 영역에 올린다.
- CPU는 프로그램 코드를 읽어 호출규약(Calling Convention)에 의해 메모리를 관리하고 명령문을 실행한다.
- 프로그램 실행을 위해 동적 메모리가 할당되면 Free Store 영역을 사용하게 된다.
- 시스템이 작동하기 위해 CPU가 임시적인 정보를 스택에 저장하게 되면 Free Store 영역을 사용하게 된다.
Free Store가 부족할 땐, Heap에서는 메모리를 할당하지 않고(NULL), Stack에서는 Stack Overflow가 발생하게 된다.
📌 메모리 구조
📌 Kernel 영역
- 하나의 프로세스에 할당되는 총 메모리 공간 중에서 유저 영역을 제외한 나머지 영역이며, 운영체제라는 하나의 소프트웨어를 실행시키기 위해서 필요한 메모리 영역
- 사용자 코드는 이 영역에서 읽거나 쓸 수 없다.
- 단일 영역으로 커널 모드를 사용하는 모든 프로세스에서 공유된다.
- 시스템 운영에 필수적이기 때문에 페이지 파일보다 RAM에 존재한다.
📌 Text(Code) 영역
- 사용자가 작성한 코드가 기계어로 저장되는 영역
- Text 영역에 저장된 명령어들을 CPU가 하나씩 가져가 처리한다.
- Read-Only
- 라이프 타임 : 프로그램 시작 ~ 프로그램 종료
📌 Data 영역
- 초기화된 전역 변수와 정적 변수가 저장되는 영역
- 프로그램 실행 시, 전역 변수와 정적 변수는 메인 함수가 호출되기 전에 데이터 영역에 할당된다.
- 라이프 타임 : 프로그램 시작 ~ 프로그램 종료
- 초기화된 Read-Only(ROM) 영역과 초기화된 Read-Write(RAM) 영역으로 더 세분화할 수 있다.
- 예를 들어,
char s[] = "hello world";
int debug = 1;
위 코드는 초기화된 Read-Write 영역에 저장된다.
const char* str = "hello world";
- 위 코드는 상수 문자열 리터럴 "hello world"의 첫 번째 문자를 가리키는 문자 포인터 변수(str)를 정의하였다.
- 이 경우 문자열 리터럴 "hellow world"는 초기화된 Read-Only 영역에 저장되고 문자 포인터 변수(str)는 초기화된 Read-Write 영역에 저장된다(런타임에 수정될 수 있기 때문).
- 마찬가지로
static int i = 10;
위 코드 또한 Read-Wirte 영역에 저장된다.
📌 BSS 영역
- 초기화되지 않은 전역 변수와 정적 변수가 저장되는 영역
- 초기화되지 않은 Data 영역을 나타내기도 하며, 'Block Started by Symbol'을 의미하는 고대 어셈블러 연산자의 이름을 따서 명명되었다.
- 이 영역의 데이터는 프로그램이 실행되기 전에 OS 커널에 의해 0으로 초기화된다.
- 초기화를 안 할 경우 문제가 생길 수 있기 때문에 존재한다.
- Read-Write
int a;
int b = 0;
const int c = 0;
void main() {
const int d = 0;
}
- 단, C++ 표준에서 꼭 const를 .rodata에 저장된다는 말이 없다. 따라서 컴파일 하기 나름인 것 같다.
📌 Stack 영역
- 프로그램에서 함수 호출에 필요한 모든 데이터가 저장되는 영역
- 함수 호출을 위해 푸시된 값 세트는 'Stack Frame'이라고 명명되고, 모든 자동 변수(함수의 지역 변수와 매개 변수 포함)와 호출자의 변수로 구성된다.
- LIFO(Lsat In First Out) 구조
- 메모리의 높은 주소부터 낮은 주소로 할당된다. (일부 아키텍처는 반대일 수 있음)
- 컴파일 시점에 크기가 결정된다.
- MSVC의 글에 따르면 x86 및 x64의 경우 1MB라고 한다.
- 라이프 타임 : 필드 시작 ~ 필드 종료
📌 Heap 영역
- 동적 메모리 할당이 발생하는 영역
- 런타임에만 크기를 알 수 있고 프로그램 실행 전에 컴파일러가 정적이지 않은 변수에 대해 프로그래머가 요청한 메모리를 할당하는 영역
- BSS 영역의 끝에서 시작하여 높은 메모리 주소 쪽으로 증가한다.
malloc
/ new
, free
/ delete
에 의해 관리된다.
- 라이프 타임 : 프로그래머에 의해 생성되고 삭제된다.
📌 상수(Constant)
- 필드 밖에서 선언된 상수 : Data 영역에 저장
- 필드 안에서 선언된 상수 : Stack 영역에 저장
- 필드 안에서 선언된 상수 문자열 : Data 영역에 저장
📌 매크로 상수(Macro Constant) / 열겨체(Enumeration)
- 매크로 상수 :
#define
은 전처리 과정에서 치환되므로 메모리 공간에 할당되지 않는다.
- 열거체 : 정숫값에 식별자를 부여한 형태이고, 매크로 상수처럼 치환되기 때문에 메모리 공간에 할당되지 않는다.