Study · 운영체제 · 페이지 폴트 · 메모리
페이지 폴트는 오류가 아니라 정상 동작이다
장면
잡아만 둔 메모리를 처음 건드리면 무엇이 일어날까? 그 일은 몇 번이나 일어날까?
$ /usr/bin/time -v ./a.out 2>&1 | grep -i "page faults"
Minor (reclaiming a frame) page faults: 12345
# 이 수가 페이지를 붙인 횟수다. 잡아만 뒀을 때는 거의 0, 다 건드리면 확 는다
아래 재생기의 ▶를 누르면 한 스텝씩 진행된다. 금색 테두리가 지금 이야기하는 곳이고, 캡션이 무슨 일이 일어났는지 말해 준다. 굵게 밑줄 친 말은 누르면 뜻이 나온다. 빨간 딱지는 그때 벌어지는 일의 이름이고, 캡션 바로 위 회색 글자는 지금 스텝이 속한 묶음의 이름이다.
카드 아래 회색 줄은 그 일이 실제로 적혀 있는 소스의 파일 이름 : 줄 번호와 함수 이름이다. 글 안에 (:669)처럼 줄 번호만 적힌 것은 바로 앞에 적은 파일의 그 줄이라는 뜻이다. 캡션 한가운데 박힌 긴 영어 이름과 괄호 속 파일 · 줄 번호도 같다 — 건너뛰고 한글만 읽어도 뜻이 통하게 써 두었다.
장면 · 닿는 순간에 붙는다
0 / 12
▶ 를 누르면 앞 항목에서 잡아만 둔 32칸을 처음 건드릴 때 무슨 일이 일어나는지 본다. 페이지 폴트는 프로그램이 부르는 것이 아니라 CPU 가 올리는 신호다. minor 폴트는 디스크에 가지 않고 끝난 폴트를 말한다.
키보드 · ← → 한 스텝 · Space 재생/멈춤 · Home 처음
페이지 폴트는 오류가 아니라 「지금 붙여 달라」는 신호다. 닿는 순간 커널이 페이지를 붙이고, 그때 비로소 물리 메모리가 준다.
어떻게 확인했나
소스 어디를 보고 적었는지와 무엇을 돌려서 쟀는지를 남긴 자리다. 처음 읽을 때는 건너뛰어도 된다.
- 폴트는 시스템 콜이 아니라 하드웨어 예외로 들어온다 — exc_page_fault(arch/x86/mm/fault.c:1492) → handle_page_fault(:1471) → do_user_addr_fault(:1216). 커널이 맨 먼저 하는 것은 lock_mm_and_find_vma(:1366)로 그 주소를 덮는 vma 를 찾는 일이고, 못 찾으면 거기서 SIGSEGV 다.
- 붙이는 차례는 handle_mm_fault(mm/memory.c:6841) → handle_pte_fault(:6514) → do_pte_missing(:6557 에서 부르고, 정의는 :4695) → do_anonymous_page(:5427, 가르는 줄은 :4697) 다. 실제로 페이지를 받아 오는 줄이 alloc_anon_folio(:5482), 페이지 표에 적는 줄이 map_anon_folio_pte_pf(:5519).
- VmRSS 가 느는 자리는 map_anon_folio_pte_pf 안의 add_mm_counter(mm, MM_ANONPAGES, ...)(mm/memory.c:5417) 하나다. mmap 경로에는 이 줄이 없다 — 12번 항목의 VmSize 와 갈리는 지점이 여기다.
- 읽기로 처음 닿으면 물리 페이지를 아예 안 준다 — 0 으로 채워진 공용 페이지를 가리키게만 하고 끝낸다(mm/memory.c:5447-5450). 내 페이지가 붙는 것은 쓰기일 때뿐이다.
- minor · major 를 가르는 줄은 mm_account_fault(mm/memory.c:6725)의 major = (ret & VM_FAULT_MAJOR) || (flags & FAULT_FLAG_TRIED)(:6757)다. VM_FAULT_MAJOR 가 서는 곳은 스왑에서 읽어 올 때(do_swap_page, :4988)이고, 그때 maj_flt(:6760), 아니면 min_flt(:6762) 가 오른다.
- 같은 1GB 를 페이지마다 한 바이트씩 건드리니 VmRSS 가 1,049,856 kB 가 됐다. /usr/bin/time 이 찍는 minor 폴트는 잡기만 했을 때 76번, 전부 건드렸을 때 262,219번이었다 — 1GB ÷ 4KB = 262,144 와 거의 같다. major 폴트는 둘 다 0 이었다. 디스크에서 읽어 올 것이 없는 익명 메모리라 그렇다.
항목 지도목차 ›
- 계정과 권한
- 1 로그인 — 로그인하면 무슨 일이 일어나나
- 2 계정 만들기 — 계정을 만들면 어디에 무엇이 쓰이나
- 3 권한 주기 — chmod 가 바꾸는 것은 어디에 있나
- 4 권한 검사 — 파일을 열 때 권한을 언제 보나
- 파일과 디렉터리
- 5 파일 만들기 — 파일을 만들면 무엇이 생기나
- 6 디렉터리 — 디렉터리를 만들면 무엇이 생기나
- 7 파일 읽기 — 파일을 읽으면 어디를 거치나
- 8 파일 지우기 — 파일을 지우면 정말 사라지나
- 프로세스
- 9 명령 실행 — 명령 하나를 치면 무슨 일이 벌어지나
- 10 파일 디스크립터 — 프로세스가 파일을 열면 무엇이 늘어나나
- 11 CPU 나누기 — CPU 하나를 여럿이 어떻게 나눠 쓰나
- 메모리
- 12 메모리 요청 — 메모리를 달라고 하면 바로 주나
- 13 페이지 폴트 — 처음 건드릴 때 무슨 일이 일어나나
- 14 OOM — 메모리가 모자라면 누가 죽나
- 네트워크
- 15 소켓 만들기 — 소켓을 만들면 무엇을 받나
- 16 연결 받기 — 연결이 들어오면 누가 먼저 받나
- 17 주고받기 — 데이터가 오갈 때 무엇이 움직이나