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

当判断不是读操作导致的缺页的时候 , 则是写操作造成 , 处理写私有的匿名页情况 , 请记住这依然是第一次访问这个匿名页只不过是写访问而已 。
2928 行会分配一个高端 可迁移的 被0填充的物理页 。 2941 设置页中数据有效 2943 使用页帧号和vma的访问权限设置页表项值(注意:这个时候页表项属性依然为只读) 。
2944-2945行 如果vma可写 , 则设置页表项值为脏且*可写*(这个时候才设置为可写) 。
2964行 匿名页计数统计 2965行 添加到匿名页的反向映射中 2967行 添加到lru链表 2969 将设置好的页表项值填充到页表项中 。
下面用图说话:
科技大本营|Linux内核虚拟内存管理之匿名映射缺页异常分析3.4 读之后写匿名页读之后写匿名页 , 其实已经很简单了 , 那就是发生COW写时复制缺页 。 下面依然看图说话:
科技大本营|Linux内核虚拟内存管理之匿名映射缺页异常分析四 , 应用层实验实验1:主要体验下内核的按需分配页策略!实验代码:mmap映射10 * 4096 * 4096/1M=160M内存空间,映射和写页前后获得内存使用情况:
1 #include2 #include3 #include4 #include 567 #define MAP_LEN (10 * 4096 * 4096)89 int main(int argc, char **argv)10 {11char *p;12int i;131415puts("before mmap ->please exec: free -m\n");16sleep(10);17p = (char *)mmap(0, MAP_LEN, PROT_READ |PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);1819puts("after mmap ->please exec: free -m\n");20puts("before write....\n");21sleep(10);2223for(i=0;i <4096 *10; i++)24p[4096 * i] = 0x55;252627puts("after write ->please exec: free -m\n");2829pause();3031return 0;32 }执行结果:
出现“before mmap ->please exec: free -m”打印后执行:
$ free -m总计已用空闲共享缓冲/缓存可用内存:15921656146279688978214交换:1629070215588出现“after mmap ->please exec: free -m”打印后执行:
$ free -m总计已用空闲共享缓冲/缓存可用内存:15921656548377188728236交换:1629070215588出现“after write ->please exec: free -m”后执行:
$:~/study/user_test/page-fault$ free -m总计已用空闲共享缓冲/缓存可用内存:15921672732277088718076交换:1629070215588我们只关注已用内存 , 可以发现映射前后基本上已用内存没有变化(考虑到其他内存申请情况存在 , 也会有内存变化)是6561M和6565M,说明mmap的时候并没有分配物理内存 , 写之后发现内存使用为6727M, 6727-6565=162M与我们mmap的大小基本一致 , 说明了匿名页实际写的时候才会分配等量的物理内存 。
【科技大本营|Linux内核虚拟内存管理之匿名映射缺页异常分析】实验2:主要体验下匿名页读之后写内存页申请情况 实验代码:mmap映射10 * 4096 * 4096/1M=160M内存空间,映射、读然后写页前后获得内存使用情况:
1 #include2 #include3 #include4 #include 567 #define MAP_LEN (10 * 4096 * 4096)89 int main(int argc, char **argv)10 {11char *p;12int i;131415puts("before mmap...pls show free:.\n");16sleep(10);?17p = (char *)mmap(0, MAP_LEN, PROT_READ |PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);1819puts("after mmap....\n");2021puts("before read...pls show free:.\n");22sleep(10);2324puts("start read....\n");252627for(i=0;i


推荐阅读