Linux内存管理之揭开mmap的神秘面纱

本文探讨了Linux内存管理中的mmap机制,详细分析了mmap在创建虚拟内存区域(vma)、读写操作触发的页错误(page fault)以及物理内存分配等方面的行为。通过对代码的跟踪,验证了mmap仅创建vma而不立即分配物理内存,读操作映射到zero page,而写操作才触发实际的物理内存分配。
摘要由CSDN通过智能技术生成

前言


我们首先来看一幅图
在这里插入图片描述Linux内存管理的最底层是buddy内存管理方案,也就是我们常说的伙伴算法,管理伙伴算法我们不做详诉,有兴趣的可以自行百度,我们这里只要知道buddy内存池中只能分配2^n个page的内存,比如1,2,4,8……个pages,然而正常使用的时候不会碰巧就需要1,2,4,8……个pages。所以基于buddy内存池,还需要有上一级的内存管理系统,内核里面采用的是slab,slub,slob;而用户空间也有自己的内存管理方案,比如基于glibc的malloc/free内存管理方案。
关于glibc的malloc内存管理方案本文先不做详诉,我们大概了解以下几点,以便对本文的话题有个更加宏观的认识:

  • 如果glibc的内存池中没有内存了,那么malloc就会通过mmap或者brk向buddy申请内存。
  • free调用不会立即将内存还给buddy,而是会还给glibc的内存池。
  • 如果glibc的内存池中还有足够的内存,那么malloc直接从glibc内存池中分配内存,不会像buddy申请内存。

以上引出了今天的话题mmap,关于mmap的行为总结下来就是一下几点:

  • mmap的时候只会创建一个vma,此vma也有可能跟之前的vma合并成一个vma,并不会真正的分配物理内存。
  • 当读mmap出来的内存的时候,会发生缺页异常,并将读所涉及到内存都映射到同一个物理页,称为zero page,zero page只有读权限,没有写权限。
  • 当写mmap出来的内存的时候,会在此发生缺页异常,并将所涉及到的内存映射到真实的物理页,并且这些物理页有写权限。

本文的目的就是从行为以及代码两个方面来印证以上描述。

mmap行为验证


以下代码用于mmap行为验证

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

#define MMAP_SIZE 0x4000
int main(char *argv[], int argc)
{
	int i;
	int tmp;
	void *addr;
	char *p;

	printf("before mmap\n");
	getchar();
	addr = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
                  -1, 0);
	printf("after mmap\n");
	getchar();
	p = (char *)addr;
	for(i=0; i< MMAP_SIZE;i++)
		tmp = p[i];

	printf("after read\n");
	getchar();

	for(i=0; i<MMAP_SIZE; i++)
		p[i] = 0x1;

	printf("after write\n");
	getchar();
 
	return 0;
}
  • mmap之前的page fault中断以及内存分配情况
    执行test程序,打印出before mmap后,通过pidof 找到测试程序的pid为2313,并获取获得如下关键信息:
# ps -o maj_flt -o min_flt -p 2313
 MAJFL  MINFL
     0     74
# pmap 2313
0000000000400000      4K r-x-- test
0000000000600000      4K r---- test
0000000000601000      4K rw--- test
00000000014e7000    132K rw---   [ anon ]
00007efc3f0c1000   1792K r-x-- libc-2.23.so
00007efc3f281000   2048K ----- libc-2.23.so
00007efc3f481000     16K r---- libc-2.23.so
00007efc3f485000      8K rw--- libc-2.23.so
00007efc3f487000     16K rw---   [ anon ]
00007efc3f48b000    152K r-x-- ld-2.23.so
00007efc3f696000     12K rw---   [ anon ]
00007efc3f6b0000      4K r---- 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值