QUESTION
가상 주소 범위가 보인다는 것은 물리 메모리가 이미 할당됐다는 뜻인가?
VMA는 연속 가상 주소 범위의 protection과 backing 규칙을 설명한다. mmap이나 exec가 VMA를 만들었다고 모든 PTE와 physical page가 즉시 준비되는 것은 아니다. 접근할 때 page fault가 file page, zero page, anonymous page를 연결한다.
/proc/PID/maps는 범위와 permission을, smaps는 RSS/PSS/private/shared accounting을 보여 준다. heap이라는 이름 하나로 malloc object, brk VMA, allocator mmap arena를 모두 설명할 수 없다.
STRUCTURE
구조 그림
maps에 VMA가 보이는 것과 모든 physical page가 resident한 것은 다르다. anonymous range는 최초 write fault에서 private page가 생긴다.
CALL PATH
호출 흐름
주소 예약, VMA 등록, PTE 설치, physical page allocation, RSS accounting이 서로 다른 시점에 일어난다.
함수 이름을 외우기 위한 그림이 아니다. 반환값, 파일 디스크립터, 메모리 매핑, 대기 큐 가운데 무엇이 다음 단계로 전달되는지 확인한다.
SOURCE COORDINATES
Linux 6.18.37 LTS 소스 위치
glibc 함수에서 멈추지 않고 syscall 구현과 커널 객체가 만나는 파일까지 내려간다. 링크는 동일한 태그의 원본 파일을 가리킨다.
| 파일 | 함수·구조체 | 여기서 볼 것 |
|---|---|---|
| mm/mmap.c | do_mmap(), mmap_region() | VMA range 선택과 maple tree 등록 |
| mm/memory.c | handle_mm_fault(), do_anonymous_page() | 접근 시 PTE와 anonymous page 준비 |
| fs/proc/task_mmu.c | show_map_vma(), show_smap() | /proc maps/smaps가 어떤 필드를 출력하는지 확인 |
COMPLETE PROGRAM
실행 예제 원본
아래 코드는 설명을 위해 중간 줄을 생략한 의사 코드가 아니다. 파일로 빌드해 실행할 수 있는 최소 예제다.
cc -std=c17 -Wall -Wextra -O2 address_space.c -o address_space01#define _DEFAULT_SOURCE
02#include <stdio.h>
03#include <stdlib.h>
04#include <sys/mman.h>
05#include <unistd.h>
06
07int main(void)
08{
09 long page = sysconf(_SC_PAGESIZE);
10 size_t length = 256UL * 1024 * 1024;
11 unsigned char *area = mmap(NULL, length, PROT_READ | PROT_WRITE,
12 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
13 if (area == MAP_FAILED)
14 return 1;
15
16 printf("pid=%ld area=%p length=%zu page=%ld\n",
17 (long)getpid(), (void *)area, length, page);
18 puts("mapping created; press Enter");
19 getchar();
20 for (size_t offset = 0; offset < length; offset += (size_t)page)
21 area[offset] = 1;
22 puts("pages touched; press Enter");
23 getchar();
24 return munmap(area, length) != 0;
25}
CODE NOTES
코드 조각별 설명
sysconf(_SC_PAGESIZE)page 크기를 4096으로 고정하지 않고 실행 환경에서 읽는다. huge page와 base page 구분은 별도다.
256UL * 1024 * 1024큰 virtual range를 예약하지만 mmap 반환 직후 RSS가 같은 양만큼 늘어날 필요는 없다.
MAP_PRIVATE | MAP_ANONYMOUSfile backing 없는 private VMA를 만든다. 최초 read는 shared zero page, write는 private anonymous page를 만들 수 있다.
area[offset] = 1각 base page에 쓰기 접근해 minor fault와 physical page allocation을 유도한다.
munmap(area, length)VMA range를 제거하고 page table/reference를 정리한다. 잘린 VMA는 분할·병합될 수 있다.
DETAILS
세부 동작
ASLR과 PIE가 주소를 바꾼다
PIE main executable, shared objects, stack, mmap base는 exec마다 달라질 수 있다. symbol offset과 mapping load bias를 결합해야 runtime address를 해석할 수 있다.
absolute pointer를 log에 저장해 다음 실행에서 재사용하는 설계는 성립하지 않는다.
RSS와 PSS는 질문이 다르다
RSS는 process page table에 resident한 page를 세고 shared page도 각 process에 포함한다. PSS는 shared page 비용을 mapping 수로 나눠 process별 비례 사용량을 추정한다.
allocator fragmentation을 볼 때 virtual size, RSS, anonymous private dirty를 함께 본다.
major/minor fault는 오류가 아니다
minor fault는 disk I/O 없이 page table을 채울 수 있는 정상 demand paging 사건이다. major fault는 backing data를 storage에서 기다려야 했음을 뜻한다.
latency-sensitive path에서는 page를 미리 touch하거나 mlock 정책을 검토하지만 memory pressure와 startup 비용을 교환한다.
OBJECTS
객체와 수명
| 대상 | 언제 생기고 없어지는가 | 확인할 값 |
|---|---|---|
vm_area_struct | mmap/exec/brk에서 생기고 munmap/exec/exit에서 제거된다 | vm_start/end, vm_flags, vm_file |
PTE | fault 또는 prefault에서 설치되고 reclaim/unmap에서 지워진다 | present, writable, dirty, accessed |
physical page/folio | fault/read-ahead에서 확보되고 map/ref가 사라지면 reclaim 가능 | mapcount, refcount, dirty |
FAILURE PATH
실패 조건과 오해하기 쉬운 부분
| 겉으로 보이는 현상 | 실제 원인 후보 | 확인 방법 |
|---|---|---|
| VIRT는 큰데 RSS는 작음 | 예약만 하고 page 미접근 | maps와 smaps Rss 비교 |
| 첫 접근 latency | demand fault 또는 file I/O | perf faults, mincore, major faults |
| mmap ENOMEM | VA range, map count, commit limit | vm.max_map_count, overcommit, address layout |
LAB
직접 확인
- 첫 Enter 전후 /proc/PID/smaps_rollup의 Rss와 Private_Dirty를 비교한다.
- read만 수행하는 loop와 write loop에서 zero page와 private page accounting 차이를 본다.
- madvise(MADV_HUGEPAGE/NOHUGEPAGE)를 적용해 AnonHugePages와 fault 수를 비교한다.
./address_spaceperf stat -e page-faults,minor-faults,major-faults ./address_spacePRIMARY REFERENCES