mmap
mmap
mmap
은 유닉스 계열 운영체제(Unix-like OS)에서 제공하는 시스템 콜(system call)로, 파일이나 디바이스를 메모리에 매핑하여 프로세스가 파일을 마치 메모리 배열처럼 직접 접근할 수 있게 해주는 기술입니다. 이 기능은 파일 입출력 성능을 크게 향상시키며, 특히 대용량 데이터 처리나 공유 메모리 기반의 프로세스 간 통신(IPC)에 널리 사용됩니다.
개요
mmap
은 "memory map"의 약자로, 파일이나 다른 리소스를 프로세스의 가상 주소 공간에 매핑하는 시스템 콜입니다. 이를 통해 프로그래머는 [read](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%85%EC%B6%9C%EB%A0%A5%ED%95%A8%EC%88%98/read)()
나 [write](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%85%EC%B6%9C%EB%A0%A5%ED%95%A8%EC%88%98/write)()
시스템 콜을 사용하지 않고도 파일을 읽거나 쓸 수 있습니다. 대신, 포인터를 통해 메모리처럼 접근하면 운영체제가 자동으로 데이터를 파일과 동기화합니다.
이 기술은 C/C++ 언어에서 주로 사용되며, POSIX 표준에 포함되어 있어 리눅스, macOS, BSD 등 대부분의 유닉스 계열 시스템에서 사용 가능합니다.
기본 사용법
mmap
은 <[sys/mman.h](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%ED%97%A4%EB%8D%94%ED%8C%8C%EC%9D%BC/sys%2Fmman.h)>
헤더에 정의되어 있으며, 다음과 같은 프로토타입을 가집니다:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
매개변수 설명
매개변수 | 설명 |
---|---|
addr |
매핑할 메모리 주소 (보통 NULL 로 지정하면 시스템이 자동 할당) |
length |
매핑할 데이터의 크기 (바이트 단위) |
prot |
메모리 보호 권한 ([PROT_READ](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%B3%B4%ED%98%B8/PROT_READ) , [PROT_WRITE](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%B3%B4%ED%98%B8/PROT_WRITE) , [PROT_EXEC](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%B3%B4%ED%98%B8/PROT_EXEC) 등) |
flags |
매핑의 특성 ([MAP_SHARED](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EA%B0%84%ED%86%B5%EC%8B%A0/MAP_SHARED) , [MAP_PRIVATE](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EB%A9%94%EB%AA%A8%EB%A6%AC%EA%B4%80%EB%A6%AC/MAP_PRIVATE) , [MAP_ANONYMOUS](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EB%A9%94%EB%AA%A8%EB%A6%AC%EA%B4%80%EB%A6%AC/MAP_ANONYMOUS) 등) |
fd |
매핑할 파일의 파일 디스크립터 |
[offset](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%ED%8C%8C%EC%9D%BC%EC%A0%91%EA%B7%BC/offset) |
파일 내 매핑 시작 위치 (페이지 경계에 맞춰야 함) |
반환값
성공 시 매핑된 메모리 영역의 시작 주소를 반환하고, 실패 시 MAP_FAILED
((void *)-1
)을 반환합니다.
해제: [munmap](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%A7%A4%ED%95%91/munmap)
매핑된 메모리는 munmap()
함수로 해제해야 합니다.
int munmap(void *addr, size_t length);
주요 특징 및 장점
1. 성능 향상
전통적인 read()
/write()
는 커널 공간과 사용자 공간 간 데이터 복사를 반복하므로 오버헤드가 큽니다. 반면 mmap
은 파일을 메모리에 매핑하여, CPU 캐시를 효율적으로 활용하고 불필요한 복사를 줄입니다.
2. 지연 로딩 (Lazy Loading)
mmap
은 전체 파일을 즉시 메모리에 올리지 않고, 필요할 때만 페이지 단위로 로딩합니다. 이로 인해 메모리 사용량을 절약할 수 있습니다.
3. 프로세스 간 공유 메모리
MAP_SHARED
플래그를 사용하면 여러 프로세스가 동일한 파일을 매핑하여 공유 메모리를 구현할 수 있습니다. 이는 프로세스 간 통신(IPC)에 매우 유용합니다.
4. 대용량 파일 처리
데이터베이스 시스템이나 로그 처리기 등에서 수 기가바이트 이상의 파일을 효율적으로 처리할 때 mmap
이 자주 활용됩니다.
사용 예제
다음은 파일을 읽기 전용으로 매핑하여 내용을 출력하는 간단한 C 예제입니다.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
exit(1);
}
struct stat sb;
if (fstat(fd, &sb) == -1) {
perror("fstat");
exit(1);
}
char *mapped = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (mapped == MAP_FAILED) {
perror("mmap");
exit(1);
}
printf("File contents:\n%s", mapped);
munmap(mapped, sb.st_size);
close(fd);
return 0;
}
이 코드는 example.txt
파일을 메모리에 매핑하고, 문자열로 출력합니다.
주의사항 및 제한
- 페이지 경계 정렬:
offset
은 일반적으로 시스템 페이지 크기(보통 4KB)의 배수여야 합니다. - 메모리 부족: 매우 큰 파일을 매핑하면 가상 메모리 부족이 발생할 수 있습니다.
- 동기화 문제:
MAP_SHARED
사용 시, 여러 프로세스가 동시에 접근하면 동기화가 필요합니다. - 플랫폼 의존성: Windows에서는 유사 기능을
[CreateFileMapping](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EC%9C%88%EB%8F%84%EC%9A%B0API/CreateFileMapping)
과[MapViewOfFile](/doc/%EA%B8%B0%EC%88%A0/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/%EC%9C%88%EB%8F%84%EC%9A%B0API/MapViewOfFile)
으로 제공합니다.
관련 시스템 콜
munmap()
: 매핑 해제[msync](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%8F%99%EA%B8%B0%ED%99%94/msync)()
: 매핑된 메모리를 디스크에 동기화[mprotect](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%B3%B4%ED%98%B8/mprotect)()
: 매핑된 메모리의 보호 권한 변경[madvise](/doc/%EA%B8%B0%EC%88%A0/%EC%8B%9C%EC%8A%A4%ED%85%9C%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%84%B1%EB%8A%A5%ED%9E%8C%ED%8A%B8/madvise)()
: 운영체제에 메모리 사용 패턴을 힌트로 제공
참고 자료
- POSIX mmap 문서
- Linux Programmer's Manual (
man 2 mmap
) - 책: "The Linux Programming Interface" by Michael Kerrisk
mmap
은 시스템 프로그래밍에서 고성능 I/O를 구현하는 핵심 도구로, 적절히 사용하면 성능과 코드 가독성을 동시에 향상시킬 수 있습니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.