please exec: free -m" 后执行: $ free -m总计已用空闲共享缓冲/缓存可用内存:15921659063178087008164交换:1629070215588 出现"before read ->p。科技大本营|Linux内核虚拟内存管理之匿名映射缺页异常分析( 五 )。" />

科技大本营|Linux内核虚拟内存管理之匿名映射缺页异常分析( 五 )

<4096 *10; i++)28printf("%d ", p[4096 * i]);29printf("\n");3031puts("after read....pls show free:\n");3233sleep(10);3435puts("start write....\n");3637for(i=0;i <4096 *10; i++)38p[4096 * i] = 0x55;394041puts("after write...pls show free:.\n");4243pause();4445return 0;46 }执行结果:出现"before mmap ->please exec: free -m" 后执行:
$ free -m总计已用空闲共享缓冲/缓存可用内存:15921659063178087008164交换:1629070215588出现"before read ->please exec: free -m"后执行:
$ free -m总计已用空闲共享缓冲/缓存可用内存:15921658664477086908178交换:1629070215588出现"after read ->please exec: free -m"后执行:
$ free -m总计已用空闲共享缓冲/缓存可用内存:15921658762478987098158交换:1629070215588出现"after write ->please exec: free -m"后执行:
$ free -m总计已用空闲共享缓冲/缓存可用内存:15921674946278987097996交换:1629070215588可以发现:读之后和之前基本上内存使用没有变化(实际上映射到了0页 , 这是内核初始化时候分配好的) , 知道写之后6749-6587=162M符合预期 , 而且打印可以发现数据全为0 。
分析:实际上 , mmap的时候只是申请了一块vma , 读的时候发生一次缺页异常 , 映射到0页 , 所有内存没有分配 , 当再次写这个页面的时候 , 发生了COW分配新页(cow中分配新页的时候会判断原来的页是否为0页 , 如果为0页就直接分配页然后用0填充) 。
五 , 总结匿名映射缺页异常是我们遇到的一种很常用的一种异常 , 对于匿名映射 , 映射完成之后 , 只是获得了一块虚拟内存 , 并没有分配物理内存 , 当第一次访问的时候:如果是读访问 , 会将虚拟页映射到0页 , 以减少不必要的内存分配;如果是写访问 , 则会分配新的物理页 , 并用0填充 , 然后映射到虚拟页上去 。 而如果是先读访问一页然后写访问这一页 , 则会发生两次缺页异常:第一次是匿名页缺页异常的读的处理 , 第二次是写时复制缺页异常处理 。


推荐阅读