为什么只读内存映射区域有脏页?

为什么只读内存映射区域有脏页?

执行(例如)以下命令来获取内存映射页列表:

pmap -x `pidof bash`

我得到这个输出: 在此输入图像描述 为什么有些只读页被标记为“脏”,即写入后需要回写?如果它们是只读的,则进程应该无法写入它们...(在提供的示例中,脏页始终为 4 kB,但我发现其他情况具有不同的值)

我还检查了 /proc/PID/smaps 并且该页面被描述为“隐私脏”。

答案1

脏页不一定需要回写。脏页是自内核上次将其标记为干净以来写入的页。数据并不总是需要保存回原始文件。

这些页面是私有的,不共享,因此它们不会被保存回原始文件中。只读文件不可能支持脏页。如果需要从 RAM 中删除该页面,它将被保存在交换区中。

只读、私有和脏页,但在内存映射文件的范围内,通常是包含需要在运行时初始化的常量的数据页,但在初始化后不会更改。例如,它们可能包含嵌入指针的静态数据;指针值取决于程序或库映射的地址,因此必须在程序启动后计算,此时页面正在读写。计算完指针后,页面的内容在程序的此实例中将永远不会更改,因此可以将页面更改为只读。看stosb 的“寻找脏内存页”带有代码片段的示例。

您可能会很少看到只读、可执行、私有、脏页;这些情况发生在一些更自由地混合代码和数据的链接器中,或者通过即时编译时。

答案2

除了案例之外吉尔斯列表:

当进程分叉时,内核可能会将其所有脏页标记为只读,并且它们将在父进程和子进程之间共享。当其中一个进程写入该页时,就会发生异常,内核将复制该页并将其标记为可写。这节省了复制最终不会被任一进程再次修改的页面的工作。 (请注意,在这种情况下,这些页面在硬件中被标记为只读,但内核知道这些页面是可写的。)

相关内容