在现代类UNIX系统中执行fork
后,我正在阅读有关使用 COW -approach的内容。
假设我们有进程 - P1。它分叉;我们得到另一个过程 - P2。
由于 COW ,它们的虚拟内存由相同的物理页面支持。
有一个页面,其中一个静态全局变量(例如,static long variable;
之外的main
)位于( .data 段)中,由物理页面A支持。
现在P1改变了它的静态全局变量;内核在处理保护错误后,将新页面(页面B)映射到P1的虚拟内存以存储该更改的变量。
P2改变其静态全局变量的方式相同,内核在处理保护错误后,将新页面(页面C)映射到P1的虚拟内存以存储更改的变量。
现在没有任何内容引用页面A. 它在哪里?我想它不是悬在空中"保持一个物理页面不被使用,从而浪费内存?
答案 0 :(得分:2)
创建页面B时,页面A上的COW标志被删除,因为页面不再共享;在修改它之前不再需要复制它。因此,P2只使用页面A,可能根本不会发生页面错误,当然也不需要复制页面。因此,没有页面C,页面A不会被未引用。
请注意,如果P1在修改页面A上的变量之前再次分叉,或者P2分叉,或两者兼有,则可能有3个或更多进程引用该页面。系统通常为存储器映射控制信息中的每个页面维护一个引用计数器,记录将页面映射到其进程存储器的进程数,并且该计数控制是否可以清除COW标志。在只有一个进程引用页面之前,COW标志仍然有效。
exec
操作将减少旧进程中所有页面的引用计数,如果引用计数变为零,则将释放页面以供重用。如果P1设置了一些显式共享内存,则即使引用计数器可能大于1,共享内存页也不会设置COW标志。
答案 1 :(得分:1)