9강 / 20강

가상 메모리 — 모두에게 16GB를 주는 거짓말

페이지 · 페이지 테이블 · TLB · 페이지 폴트

가상 메모리 — 모두에게 16GB를 주는 거짓말
모든 프로그램은 자기가 메모리를 독차지한다고 믿습니다. 그 착각을 유지해 주는 게 MMU입니다.

이상한 사실 하나. ps aux 를 쳐 보면 워커 프로세스마다 VIRT(가상 메모리)가 1GB씩 잡혀 있습니다. 워커가 3개면 3GB네요. 그런데 실제 메모리는 그렇게 안 씁니다.

그 이유가 가상 메모리입니다.

거짓말의 구조

모든 프로그램은 자기가 0번지부터 쭉 이어진 넓은 메모리를 혼자 쓴다고 믿습니다. 실제로는 그 주소들이 물리 메모리 여기저기에 흩어져 있어요.

📖
가상 주소
프로그램이 믿는 주소
"0x7f3a…에 내 데이터가"
🗺️
페이지 테이블
번역표
가상 → 물리
🏠
물리 주소
진짜 램의 자리
흩어져 있어도 됨

이 번역을 해 주는 하드웨어가 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 쓰고 있나요?
🤔 확인 문제
vmstat의 si/so 칸에 계속 큰 숫자가 찍히고 있습니다. 무슨 상황인가요?