前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C|内存管理|COW in Linux

C|内存管理|COW in Linux

作者头像
朝闻君
发布2021-11-22 11:21:43
2.5K0
发布2021-11-22 11:21:43
举报

简介

众所周知,在fork时,属于进程private的内存页将会进行COW机制。所谓COW,就是一个资源如果需要值拷贝,在读时不创建出副本,仅当写时再创建。这样的话,就可以方便地判断出什么资源需要真的进行拷贝,而能够共享则无需拷贝,从而减少了复制的开销。

这个流程分为两部分:

Fork

设置父子进程的所有内存页的标志为write protected,

而在mmap中被标识为shared的内存则会通过wp_page_reuse标记为wriable

因为谁先写不知道,所以两者都应该是wp,都能进行COW机制。

这里产生了一个问题:

假如父子进程都使用COW,那么在子进程已经copy过的情况下,父进程再copy一次就会造成浪费。(此时原本的一个物理页会对应三个物理页,copy两次)

而且父子同时使用副本的话,原页在没有进程使用的情况下应该如何释放?如果使用计数的话,我们可以知道这个页在cnt==0时应该gc,但是假如我们已经知道了计数,我们完全可以在cnt==1时就不再复制。(此时原本的一个物理页会对应两个物理页,copy1次)

Linux中,也的确很节省地使用了这样的方式。

COW

首先和常识相同,write这些页会触发page fault:

handle_pte _fault

linux使用handle_pte_fault函数处理:

如果vma是writable但是却触发了write fault,则调用do_wp_page(write protect)

do_wp_page

在这个函数里,kernel将会根据物理页遍历所有对应的虚拟页(使用链表)求map cnt,如果map cnt为1,说明当前物理页仅被一个进程使用,不需要COW。(这个过程加锁,防止cnt不同步)。这种情况下,则调用 wp_page_reuse 。

wp_page_reuse

这个函数会在两种情况下调用,要么是上述map cnt==1,要么是mmap里声明为shared(VM_SHARED),原本write_protect的页会直接被标识为writable,即跳过copy。

总结

COW机制下,父子进程的页都会被标记为write protect

  • 父子进程均有可能进行copy
  • 最后一个写的进程不会进行copy,而是直接使用原本的物理页。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • Fork
  • COW
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档