linux-丢弃脏的写时复制页

有没有一种方法可以通过MAP_PRIVATE创建写时复制映射,写入一些数据(即弄脏某些页面),然后放弃所做的更改,而无需使用munmap和re-mmaping?目标是为给定的映射维护相同的虚拟地址(如果我取消映射&然后再次映射相同的文件,则不能保证会发生这种情况),但是要立即丢弃所有我的COW更改.

我的理解是,尝试通过提示地址并使用MAP_FIXED标志来重新映射空间可能会产生这种效果.但是我不确定我对MAP_FIXED文档的解释是否正确,还是可以保证这种行为.

引用mmap(2)文档:

If the memory region specified by addr and len overlaps pages of any existing
mapping(s), then the overlapped part of the existing mapping(s) will be 
discarded.

在这种情况下,“丢弃”是否意味着将丢弃所有COW页面,并且从相应页面进行的新读取将出错并反映磁盘上的更改?

解决方法:

如果您执行与现有映射重叠的mmap操作,则Linux内核将草稿现有映射的重叠部分,就像先对它们进行取消映射一样.因此,例如,如果您将帧缓冲区映射到以前的共享库,则该内存现在与共享库无关.它指向帧缓冲区.

删除的映射中的基础页面对象独立于映射而存在:页面是引用计数对象.当两个地图共享同一页面的视图时,仅是由于在不同的视图中“安装”了同一页面.当一个页面变脏然后被取消映射时,这不会创建依赖关系,即必须在新映射之前将脏页面写出.在清除原始脏页(例如,文件支持的共享映射的一部分)之前,虚拟内存已经可以重新分配给新的映射(例如一块图形帧缓冲区).

关于丢弃映射:我认为您不能这样做.就是说,如果您有一个应该将脏页刷新到基础文件的映射,则无法写入该内存,然后迅速对其进行取消映射(或映射其上的某些内容),以希望永远不会完成写入.在Linux的madvise API中,似乎有MAP_REMOVE操作,但是根据手册页,它似乎仅适用于tmpfs和shmfs.我认为阻止写操作发生的唯一方法是执行历史悠久的仪式,即“潜水电源开关”.

有一种方法可以映射文件对象以使更改不会传播:即MAP_PRIVATE(与MAP_SHARED相反).例如,像gdb这样的调试器需要MAP_PRIVATE,这些调试器需要能够将断点放入可执行文件或共享库中,而不会在每个运行的进程(以及磁盘上的副本)中向该可执行文件或库的每个实例中抛出陷阱指令!).

如果您的MAP_PRIVATE具有已修改的零件,并且您取消映射(或那些零件)或在它们上面映射某些东西,我相信它们将被丢弃.这些页面应该是写时复制的,因此使它们变脏的过程应该包含唯一的参考.当它们未映射时,其引用计数将降为零,并且由于它们是私有页面,因此它们会陷入困境.

上一篇:c-使用不可映射的文件系统测试软件


下一篇:频繁分配释放内存导致的性能问题的分析--brk和mmap的实现