mmap은 파일이나 디바이스를 메모리처럼 접근하게 해주는 시스템 콜입니다. read/write 없이 포인터로 파일을 다룰 수 있어서, 대용량 파일 처리와 프로세스 간 공유 메모리에 널리 사용됩니다.


mmap이란

mmap(memory-mapped I/O) 은 파일이나 디바이스를 프로세스의 가상 주소 공간에 매핑하는 시스템 콜입니다.

mmap 동작 원리

PLAINTEXT
일반 파일 I/O:
프로세스 버퍼 ←── read() ←── 커널 버퍼 ←── 디스크
프로세스 버퍼 ──→ write() ──→ 커널 버퍼 ──→ 디스크

mmap I/O:
프로세스 가상 메모리 ←──→ 페이지 캐시 ←──→ 디스크
(포인터로 직접 접근)     (자동 동기화)
C
#include <sys/mman.h>

// 파일을 메모리에 매핑
void *addr = mmap(
    NULL,           // 커널이 주소 결정
    file_size,      // 매핑 크기
    PROT_READ | PROT_WRITE,  // 읽기/쓰기 권한
    MAP_SHARED,     // 변경사항을 파일에 반영
    fd,             // 파일 디스크립터
    0               // 파일 오프셋
);

// 매핑된 메모리에 직접 접근
char first_byte = ((char*)addr)[0];  // read() 호출 없이!

// 매핑 해제
munmap(addr, file_size);

매핑 유형

파일 매핑 (File-backed Mapping)

파일의 내용을 메모리에 매핑합니다.

PLAINTEXT
MAP_SHARED:  변경 → 파일에 반영 / 다른 프로세스와 공유
MAP_PRIVATE: 변경 → COW로 프로세스 전용 복사본 생성 (파일에 반영 안 됨)

익명 매핑 (Anonymous Mapping)

파일 없이 메모리만 할당합니다.

C
// 익명 매핑: 파일 없이 메모리 할당
void *mem = mmap(NULL, size, PROT_READ | PROT_WRITE,
                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  • malloc()의 대용량 할당이 내부적으로 mmap을 사용 (glibc에서 보통 128KB 이상)
  • 공유 익명 매핑(MAP_SHARED | MAP_ANONYMOUS): 부모-자식 프로세스 간 공유 메모리

mmap vs read/write

항목read/writemmap
데이터 복사커널→유저 버퍼 복사 필요복사 없음 (직접 접근)
시스템 콜매번 필요최초 mmap 한 번
랜덤 접근lseek + read포인터 연산
대용량 파일버퍼 크기만큼 반복전체를 메모리처럼 사용
캐시커널 + 유저 버퍼 2중페이지 캐시만 (zero-copy)

활용 사례 사례

데이터베이스

  • MongoDB: 과거에 스토리지 엔진이 mmap 기반 (MMAPv1)
  • SQLite: WAL 모드에서 mmap 사용 가능
  • LMDB: mmap 기반 키-값 저장소

IPC (프로세스 간 통신)

C
// 공유 메모리 생성 (POSIX)
int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
ftruncate(fd, SHM_SIZE);
void *ptr = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

// 다른 프로세스에서 같은 공유 메모리 열기
int fd2 = shm_open("/my_shm", O_RDWR, 0666);
void *ptr2 = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0);

실행 파일 로딩

프로그램 실행 시 ELF 바이너리를 mmap으로 메모리에 매핑합니다. 코드 영역은 여러 프로세스가 공유할 수 있습니다.


주의점

  • SIGBUS: 파일 크기를 넘는 영역에 접근하면 발생
  • msync: MAP_SHARED일 때 변경사항을 디스크에 강제 플러시
  • 작은 파일의 순차 읽기에는 read()가 더 나을 수 있음 (mmap 설정 오버헤드)

핵심 포인트

  • mmap이 빠른 이유: 커널-유저 버퍼 간 복사가 없음 (zero-copy)
  • Demand Paging과 연결: mmap 호출 시 바로 읽지 않고, 실제 접근할 때 페이지 폴트로 로드
  • MAP_SHARED vs MAP_PRIVATE: 공유 vs COW — IPC면 SHARED, 읽기 전용이면 PRIVATE

정리

mmap은 파일 I/O를 메모리 접근으로 추상화하여 성능과 편의성을 모두 제공합니다. 데이터베이스, IPC, 실행 파일 로딩 등 시스템 프로그래밍 전반에 활용되며, 실제로는 zero-copy 개념과 페이지 캐시 연결을 설명할 수 있으면 좋습니다.

댓글 로딩 중...