mmap的一些琐碎

本文分享了使用Linux mmap API时遇到的问题与解决方法,重点讲述了offset参数的使用和资源管理的重要性。通过实际案例分析,强调了遵循API文档和正确释放资源以避免内存泄露的必要性。

linux用来映射文件的api

       void  *  mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);

官方的描述不再多说,直说一些教训么么。

一个是offset,事实上man文档也是有滴, offset should be a multiple of the page size as  returned  by  getpage-
       size(2).

但是用的时候没有仔细阅读,结果就悲了个剧,我第一次从文件的0开始映射,第二次增加1000再映射,但是屡次返回失败。这个时候就找上了google(再一次感叹,伟大的google,但是让人都不愿意去思考),答案就很简单,一定是某一页的倍数,其实也好理解,修改为4096之后,就木有问题。


第二个,如果多次mmap,那么一定要配对munmap,否则必然会造成资源泄露

### ### MMAP 技术原理 MMAP(内存映射)是一种操作系统提供的机制,它允许将文件或设备的内容直接映射到进程的虚拟地址空间中。通过这种映射,应用程序可以像访问内存一样访问文件内容,而无需使用传统的 `read()` 和 `write()` 系统调用。当程序访问映射区域时,操作系统会通过页表将文件的物理页与进程的虚拟内存页建立对应关系,从而实现高效的 I/O 操作[^4]。 在实现上,`mmap()` 系统调用负责将文件映射到进程的地址空间,内核会按需将文件内容加载到物理内存中。当程序访问尚未加载的内存区域时,会触发缺页异常(page fault),系统自动从磁盘读取相应文件内容并映射到内存。这种机制避免了显式调用 `read()` 和 `write()` 所带来的上下文切换和数据复制开销,提升了 I/O 性能[^3]。 ### ### 使用场景 MMAP 技术适用于需要频繁访问大文件或需要高效随机访问的场景。例如,在数据库系统中,MMAP 可用于将数据库文件直接映射到内存中,从而避免频繁的 I/O 操作。此外,它也广泛应用于日志文件读写、内存映射共享库、以及需要共享内存的多进程通信场景。 在 RocketMQ 和 Redis 等高性能系统中,MMAP 被用来优化磁盘 I/O 操作。例如,Redis 使用 MMAP 来加载 RDB 快照文件,而 RocketMQ 使用 MMAP 来实现高效的日志写入和检索,从而提升整体性能[^4]。 ### ### 优势 MMAP 的主要优势在于减少数据复制和上下文切换次数,从而提升 I/O 效率。传统的文件读写操作需要通过 `read()` 或 `write()` 系统调用在用户空间和内核空间之间进行数据复制,而 MMAP 则通过将文件内容直接映射到用户空间,省去了这一过程。这种机制在处理大文件或需要频繁访问的场景下,能显著降低 CPU 开销和内存消耗。 此外,MMAP 支持多个进程共享同一段内存区域,从而实现高效的进程间通信(IPC)。这种方式不仅减少了内存占用,还简化了同步和数据共享的实现难度。在 Java 中,`MappedByteBuffer` 提供了基于 MMAP 的内存映射支持,使得 NIO 在处理大文件、高并发和随机访问场景下表现出色[^2]。 ### 示例代码 以下是一个使用 `mmap` 读取文件内容的 C 语言示例: ```c #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> int main() { int fd = open("example.txt", O_RDONLY); if (fd == -1) { perror("open"); return 1; } struct stat sb; if (fstat(fd, &sb) == -1) { perror("fstat"); return 1; } char *addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { perror("mmap"); return 1; } printf("File content:\n%.*s\n", (int)sb.st_size, addr); if (munmap(addr, sb.st_size) == -1) { perror("munmap"); return 1; } close(fd); return 0; } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值