1.什么是内存映射文件
内存映射文件,就是把磁盘上的物理文件映射至进程地址空间中,使用内存映射文件的特性是,所有的I/O都是在内核掩盖下完成,我们只需编写存取内存映射区中各个值的代码,也就是不需要调用read/write/lseek。
如图示:
2.内存映射文件与read文件时物理内存占用区别
需要了解物理内存和进程空间地址的映射关系。
可以通过 top -p $pid 查看进程使用的虚拟内存与物理内存
VIRT:虚拟内存 KB
RES:物理内存 KB
也可以通过cat /proc/$pid/status 查看进程使用的虚拟内存与物理内存
VmHWM:虚拟内存 KB
VmRSS:物理内存 KB
调用read函数时,会将文件内容读取至物理内存中,并映射至进程空间地址。
调用内存映射文件,并不需要马上将文件内容拷贝至物理内存,由缺页中断处理。
假设用read函数读取了一个32MB的文件,会发现进程的虚拟内存和物理内存大小马上增加了32MB,
而用内存映射文件,进程的物理内存并不会马上增加32MB。
3.什么是缺页中断
进程线性地址空间里的页面不必常驻内存,在执行一条指令时,如果发现他要访问的页没有在内存中,那么停止该指令的执行,并产生一个页不存在异常,对应的故障处理程序可通过从外存加载该页到内存的方法来排除故障,之后,原先引起的异常的指令就可以继续执行,而不再产生异常。
4.内存映射文件与read/write文件的效率对比(建议抱着怀疑的心态阅读此段)
1,当调用read函数时,先要经过系统调用,把文件内容拷贝至内核的高速缓存区(参考free命令的cache),然后再把数据从高速缓存区拷贝至用户态内存,实际是两次数据拷贝。
2,当调用write函数时,先把用户态内存的数据拷贝至内核的高速缓存区(参考free命令的buffer),然后再把数据从高速缓存区拷贝至磁盘的物理文件,也是两次数据拷贝。
3,虽然mmap少了一次系统调用,并不意味着绝对更快,更多的性能对比请查阅文章: