운영체제는 각 프로세스마다 메모리 모델을 만들어 관리합니다. 이를 이해하는 것은 프로그램이 실행되는 메커니즘을 정확히 파악하는 데 필수입니다. 본 글에서는 가상 메모리와 프로세스 메모리 구조를 분석하고, 각 영역(Stack, Heap, Text, Global)의 동작을 자세히 살펴보겠습니다.
1. 운영체제의 가상 메모리 관리 개요
가상 메모리란?
가상 메모리(Virtual Memory)는 실제 물리 메모리(RAM)의 크기보다 더 큰 메모리 공간을 추상화하여 제공하는 기술입니다. 프로세스는 자신의 전체 메모리 공간을 갖는 것처럼 동작하며, 실제 메모리 할당은 운영체제가 제어합니다.
- 프로세스는 자신만의 4GB 공간(32bit 기준, 64bit에서는 훨씬 더 큼)을 가진 것처럼 동작
- 가상 주소 ↔ 실제 물리 주소는 MMU(Memory Management Unit)와 운영체제 커널이 매핑 관리
2. 프로세스 메모리 구조 (프로세스 주소 공간)
전체 메모리 구조
- 프로세스
- 운영체제로부터 시스템 자원을 할당받는 작업 단위
- 컴퓨터에서 실행 중인 동적인 상태의 프로그램
- 프로세스당 하나 이상의 스레드를 포함 -> 각 스레드는 독립적으로 실행
- 독립된 메모리 영역: Code, Data (GVAR, BSS) , Heap, Stack 구조의 메모리 영역을 다른 프로세스와 공유하지 않음
높은 주소
+-----------------+
| 커널 영역 |
+-----------------+
| Stack | ← 함수 호출 시 지역변수, 리턴주소
| (자동 할당) |
+-----------------+
| Heap | ← malloc/new 등 동적 메모리
| (동적 할당) |
+-----------------+
| Data (GVAR, BSS)| ← 전역/정적 변수
+-----------------+
| Text Code | ← 실행 코드(명령어)
+-----------------+
낮은 주소
| 영역 | 설명 | 예시 |
| Text | 실행 코드 영역. 읽기 전용, 실행 가능 | 함수 정의, main 등 |
| GVAR (Initialized) | 초기화된 전역 변수, 정적 변수 저장 | int x = 10; |
| BSS (Uninitialized) | 초기화되지 않은 전역/정적 변수 | static int a; |
| Heap | 런타임 중 동적 메모리 할당 (malloc 등) | int *p = malloc() |
| Stack | 함수 호출 시 생성되는 지역 변수, 리턴 주소 등 | int main() { int x; } |
3. 리눅스에서 가상 메모리 및 프로세스 메모리 확인 방법
시스템 전체 메모리 확인
| 명령어 | 설명 |
free -h |
전체 메모리 사용량 (RAM, Swap 포함) |
vmstat |
메모리, CPU, I/O 등 상태 요약 |
top / htop |
실시간 프로세스 메모리 사용량 |
cat /proc/meminfo |
메모리 관련 상세 통계 제공 |
프로세스별 메모리 확인
| 명령어 | 설명 |
cat /proc/<PID>/maps |
프로세스 메모리 맵, 세그먼트별 주소/권한 |
cat /proc/<PID>/smaps |
메모리 사용량(RSS, PSS 등) 상세 |
pmap <PID> |
메모리 매핑 상태 요약 |
ps aux |
전체 프로세스의 메모리(RSS, %MEM 등) 확인 가능 |
4. Node.js에서 Heap 메모리 분석
Node.js에서는 V8 엔진 기반의 힙을 관리합니다. 동작 중에도 힙 메모리를 실시간 추적하거나, 스냅샷으로 분석할 수 있습니다.
방법 1: process.memoryUsage()
console.log(process.memoryUsage());
출력 예:
{
rss: 26517504,
heapTotal: 5685248,
heapUsed: 3441280,
external: 8272
}
| 필드 | 설명 |
rss |
전체 프로세스의 메모리(RAM 포함) |
heapTotal |
힙에 할당된 총 메모리 |
heapUsed |
실제 사용 중인 힙 메모리 |
external |
네이티브 모듈이 사용하는 메모리 |
방법 2: DevTools + Heap Snapshot
node --inspect index.js
- 크롬에서
chrome://inspect접속 → Heap Snapshot 추출 - 힙 내 객체별 할당 상태 추적 가능
방법 3: heapdump 모듈
npm install heapdump
const heapdump = require('heapdump');
heapdump.writeSnapshot('heap.heapsnapshot');
정리
- 프로세스는 독립된 주소 공간을 가지고 있으며, 각 영역은 서로 다른 목적과 할당 방식으로 관리된다.
- 운영체제는 페이지 테이블과 가상 메모리를 통해 효율적이고 안정적으로 메모리를 분배한다.
- 실제 프로그램(Node.js 등)도 힙/스택 구조를 활용하며, 메모리 사용은 도구로 실시간 분석 가능하다.
참고자료
- http://pages.cs.wisc.edu/\~remzi/OSTEP/
- https://nodejs.org/api/process.html#processmemoryusage
- https://www.geeksforgeeks.org/c/memory-layout-of-c-program/
'CS' 카테고리의 다른 글
| 파서(Parser)란? (0) | 2025.07.17 |
|---|---|
| JSON과 XML: 웹 데이터 교환 방식 비교 분석 (1) | 2025.07.16 |
| 리눅스(Linux)란 무엇인가? (0) | 2025.07.16 |
| git vs GitHub (0) | 2025.07.15 |