At a Glance
executable code -> read + execute
read-only constants -> read
global/static data -> process lifetime
heap allocations -> allocator / runtime lifetime
thread stack -> one stack per thread
mapped regions -> files, libraries, reserved memory실제 주소 배치와 영역 이름은 실행 형식, 운영체제, linker, runtime에 따라 달라집니다. 면접용 네 칸 그림은 수명과 용도를 설명하는 모델이지 모든 프로세스의 고정 주소표가 아닙니다.
수명과 권한
code 영역은 실행 명령을 담고 일반적으로 쓰기와 실행 권한을 동시에 주지 않도록 관리합니다. 초기화된 전역·정적 데이터와 초기값이 없는 데이터도 실행 이미지와 process 수명에 연결됩니다.
heap은 실행 중 크기와 수명을 동적으로 정하는 할당에 사용됩니다. C++의 new, C의 malloc, 관리 runtime의 객체 할당은 세부 관리 주체가 다르지만 함수 호출 하나보다 오래 살아야 하는 데이터를 다룰 수 있습니다.
각 thread는 독립된 stack을 가집니다. 함수 호출 frame, 반환 위치, 일부 지역 상태가 이 흐름과 연결됩니다. 정확히 무엇이 stack에 놓이는지는 compiler 최적화와 ABI에 따라 달라지므로 “지역 변수는 무조건 stack”이라고 단정하지 않습니다.
오류와 연결
stack overflow -> 너무 깊은 호출, 큰 stack frame
heap leak -> 더 이상 필요 없는 allocation을 계속 보유
use-after-free -> 수명이 끝난 heap object를 다시 접근
access violation -> 허용되지 않은 주소 또는 권한으로 접근메모리 영역을 나누어 보는 이유는 주소를 외우기 위해서가 아니라 누가 수명을 관리하고 어떤 접근이 허용되는지 판단하기 위해서입니다.
자주 틀리는 점
- reference type이면 무조건 heap, value type이면 무조건 stack이라고 일반화하지 않습니다.
- stack은 process 전체가 하나를 공유하지 않고 thread마다 별도로 가집니다.
- free space가 있다고 연속된 큰 allocation이 항상 성공하는 것은 아닙니다.
- 주소가 null이 아니어도 이미 수명이 끝났다면 유효한 pointer가 아닙니다.
참고 링크
2 sources