9강 / 20강
가상 메모리 — 모두에게 16GB를 주는 거짓말
페이지 · 페이지 테이블 · TLB · 페이지 폴트
이상한 사실 하나. ps aux 를 쳐 보면 워커 프로세스마다
VIRT(가상 메모리)가 1GB씩 잡혀 있습니다. 워커가 3개면 3GB네요.
그런데 실제 메모리는 그렇게 안 씁니다.
그 이유가 가상 메모리입니다.
거짓말의 구조
모든 프로그램은 자기가 0번지부터 쭉 이어진 넓은 메모리를 혼자 쓴다고 믿습니다. 실제로는 그 주소들이 물리 메모리 여기저기에 흩어져 있어요.
이 번역을 해 주는 하드웨어가 MMU입니다. CPU 안에 들어 있어요.
페이지 — 4KB짜리 조각
주소 하나하나를 번역하면 표가 너무 커집니다. 그래서 4KB(4096바이트) 덩어리 단위로 번역해요. 이 덩어리를 페이지라고 합니다.
이 서버의 페이지 크기입니다.
bash
브라우저에서 실행
왜 페이지 테이블이 여러 단계인지.
Python
브라우저에서 실행
가상 메모리가 주는 것들
| 기능 | 어떻게 | 관리자에게 무슨 뜻인가 |
|---|---|---|
| 격리 | 프로세스마다 다른 번역표 | 한 프로세스가 죽어도 다른 것은 안전 |
| 공유 | 같은 물리 페이지를 여럿이 가리킴 | 워커 3개가 같은 파이썬 라이브러리를 한 벌만 씀 |
| 과다 할당 | 실제로 쓸 때 물리 페이지를 준다 | VIRT는 크지만 RES는 작다 |
| 스왑 | 안 쓰는 페이지를 디스크로 내림 | 메모리보다 많이 쓸 수 있지만 느려진다 |
| 보호 | 페이지마다 읽기/쓰기/실행 비트 | 6강의 NX 비트가 여기 있다 |
VIRT · RES · SHR 읽는 법 — 관리자의 필수 기술
top에서 이 세 칸의 뜻을 정확히 아는 게 메모리 문제 진단의 절반입니다.
- VIRT — 프로세스가 주장하는 주소 공간. 대부분 허풍이다. 무시해도 된다.
- RES(RSS) — 진짜 물리 메모리를 얼마나 잡고 있나. 이게 중요하다.
- SHR — 그중 다른 프로세스와 나눠 쓰는 부분(라이브러리 등)
VIRT는 크고 RES는 작습니다. 워커 3개의 RES를 더해 보세요.
bash
브라우저에서 실행
페이지 폴트 — 항상 나쁜 건 아니다
번역표를 봤는데 "이 페이지는 아직 물리 메모리에 없다"고 나오면 페이지 폴트가 납니다. CPU가 잠깐 멈추고 커널이 나서서 페이지를 채워 넣어요. 두 종류가 있습니다.
- 마이너 폴트 — 페이지는 이미 메모리에 있는데 표만 안 이어져 있었다. 아주 빠르다(마이크로초). 프로그램 시작할 때 잔뜩 난다. 정상.
- 메이저 폴트 — 진짜로 디스크에서 읽어 와야 한다. 밀리초 단위로 멈춘다. 이게 많으면 비상이다.
si(스왑 인)와 so(스왑 아웃)가 0이면 건강합니다.
bash
브라우저에서 실행
🤔 확인 문제
top에서 워커 프로세스의 VIRT가 1.0GB, RES가 340MB 입니다. 이 서버는 메모리를 몇 MB 쓰고 있나요?해설 VIRT는 '이만큼 주소를 잡아 뒀다'는 약속일 뿐이고, 실제로 물리 메모리를 차지한 건 RES입니다. 게다가 RES 중에도 다른 프로세스와 공유하는 SHR 부분이 있어서, 워커들의 RES를 단순히 더하면 실제보다 많게 나옵니다.
🤔 확인 문제
vmstat의 si/so 칸에 계속 큰 숫자가 찍히고 있습니다. 무슨 상황인가요?해설 si = swap in, so = swap out 입니다. 메모리(85ns)에 있어야 할 것을 SSD(90,000ns)에서 가져오는 중이니 응답이 무너집니다. 해결은 메모리를 늘리거나, 워커 수를 줄이거나, 메모리를 덜 쓰도록 고치는 것이지 CPU를 바꾸는 게 아닙니다.