一、整体概念1. mmap全称 memory map内存映射 作用将文件/匿名内存映射到进程的虚拟地址空间进程直接通过指针读写这块内存等价于读写文件/共享内存大幅减少IO拷贝。2. munmap全称 unmap memory解除内存映射 作用释放 mmap 申请的虚拟内存区域切断进程地址空间和文件/共享内存的关联是 mmap 配套释放函数必须成对使用否则内存泄漏。二、mmap 函数原型#include sys/mman.hvoid *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);返回值成功返回映射区起始指针失败返回 MAP_FAILED。参数详解addr 期望映射到的虚拟地址填 NULL 让内核自动分配推荐。length 要映射的字节长度。prot 内存访问权限PROT_READ可读PROT_WRITE可写PROT_EXEC可执行flags 映射模式二选一核心MAP_SHARED共享映射 修改内存会同步到磁盘其他进程可见读写文件用这个。MAP_PRIVATE私有映射写时复制 COW 修改只会在当前进程生效不会改动原文件。 额外标记MAP_ANONYMOUS 匿名映射无文件用于进程间共享内存fd 文件描述符 映射普通文件填 open 得到的fd匿名映射填 -1。offset 文件偏移 从文件哪个位置开始映射必须是系统页大小通常4096的整数倍。三、munmap 函数原型int munmap(void *addr, size_t length);addrmmap 返回的映射起始地址length和 mmap 传入的长度保持一致 返回值成功0失败-1munmap 做了什么切断虚拟地址和内核页缓存/磁盘文件的映射关系释放该段虚拟内存进程再也不能访问这片地址若是 MAP_SHARED 修改过的数据会由内核异步刷盘不保证立刻落地重要数据要提前调用 msync进程退出时内核会自动执行 munmap但规范代码必须手动调用。四、两种映射场景场景1文件映射最常用流程 open 打开文件 → mmap 把文件映射到内存 → 指针直接读写 → msync可选强制刷盘→ munmap 释放 → close 关闭文件。数据优势传统 read/write 存在两次拷贝磁盘→内核缓存→用户缓冲区mmap 只有一次DMA拷贝零用户缓冲区拷贝性能更高。场景2匿名共享映射进程间IPCflags MAP_SHARED | MAP_ANONYMOUSfd-1 父子进程共享同一块物理内存不用创建磁盘文件用来做简易共享内存。五、简单可运行示例#include stdio.h#include stdlib.h#include unistd.h#include fcntl.h#include sys/mman.h#include sys/stat.hint main() {// 1. 打开文件int fd open(test.txt, O_RDWR);if (fd 0) {perror(open); exit(1);}// 获取文件大小struct stat st;fstat(fd, st);size_t len st.st_size;// 2. mmap 创建映射char *p mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (p MAP_FAILED) {perror(mmap); close(fd); exit(1);} // 直接操作内存等价操作文件printf(文件内容%s\n, p);p[0] X; // 修改会同步到文件// 3. munmap 解除映射关键释放步骤if (munmap(p, len) -1) {perror(munmap);}close(fd);return 0;}六、核心特性与注意事项mmap 特点懒加载调用 mmap 时不会加载文件到内存访问地址触发缺页中断才从磁盘读数据按页分配最小单位一页4KB映射很小文件会浪费内存随机读写友好数据库、大文件解析大量使用。munmap 常见坑地址、长度必须和 mmap 严格对应否则释放失败munmap 只是解除映射不关闭文件描述符fd 仍需手动 close忘记调用 munmap 会造成虚拟内存泄漏长期运行服务内存占用持续上涨未 msync 直接 munmap修改的数据内核会后台慢慢刷盘程序崩溃可能丢数据。七、mmap 和 munmap 配对总结mmap分配一段虚拟内存绑定文件/共享内存拿到可读写指针业务逻辑通过指针读写数据munmap归还虚拟内存解除映射是 mmap 必不可少的收尾操作。0voice · GitHub