mmap()

事例代码:

//------------------------------------------------mmap.c-----------------------------------------------------------

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>

int main(int argc, char **argv)
{
    int fd = -1;
    struct stat f_stat;
    unsigned char *start = NULL;
   
    if (argc != 2)
        return -1;
       
    if ((fd = open(argv[1], O_RDONLY)) == -1)
        return -1;
    if (fstat(fd, &f_stat))
        return -1;
       
    if ((start = mmap(start, f_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
        return -1;
       
    if (munmap(start, f_stat.st_size))
        return -1;
    close(fd);    

//-------------------------------file end-------------------------------------------------------------------------------

    mmap()是将指定的文件利用虚拟内存技术映射到内存中去,在内存中建立页表项,但mmap()调用并没有立即在内存中并没有建立页表项,只有使用到某个地址空间时才给此页面分配空间,要涉及到页面置换,因而需要有一定的物理内存做支撑,内存太小的话刚置入内存中的页面又要被交换到磁盘上,mmap的性能将大打折扣。

    mmap的优点主要在为用户程序随机的访问,操作,文件提供了一个方便的操作方法;其次就是为不同进程共享大批量数据提供高效的手段;另外就是对特大文件(无法一次性读入内存)的处理提供了一种有效的方法。


madvise():

   mmap()虽然为数据分配了连续的内存单元,但是mmap()后并没有立即读入数据,而是通过产生缺页中断再读入数据。

   例如当需要访问第一个字节的数据时,这时系统检测到内存中并没有需要的数据,这时产生一个缺页中断,再从磁盘中读入1页(4096)的数据,

   当访问第4097字节数据时,又会产生一次缺页中断,读入数据....,依此类推,直到读入所有数据


   显然,这会极大的影响系统性能,因为频繁的缺页中断会打断CPU的工作流程

   通过madvise()可以解决这个问题,读入所需的数据,避免频繁的中断

08-01
### ### 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; } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

duanbeibei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值