我正在尝试为无交换系统实现一个文件支持的内存分配器。
对于每个新分配,我使用 mkstemp
创建一个临时文件作为后台存储,mmap
将其作为 MAP_SHARED
以允许交换页面当系统的内存压力很高时到后台。我想我已经让这部分工作了。
但是,我在实现释放案例时遇到了困难。
由于在释放时,后台存储的内容、驻留页面或脏页面的内容都不再重要,最快的方法是删除并释放所有驻留页面,并保持后台不变.但是我没有找到可以执行此操作的 madvice
标志。
MADV_DONTNEED
似乎过多,因为它会将脏页提交到后台存储。 (不正确,请参阅下面的答案)
MADV_DONTNEED
After a successful MADV_DONTNEED operation, the semantics of memory access in the specified region are changed: subsequent accesses of pages in the range will succeed, but will result in either repopulating the memory contents from the up-to-date contents of the underlying mapped file (for shared file mappings, shared anonymous mappings, and shmem-based techniques such as System V shared memory segments) or zero-fill-on-demand pages for anonymous private mappings.
MADV_REMOVE
似乎也过分了,因为它不仅会删除驻留页面,还会删除后台存储本身。
MADV_REMOVE
Free up a given range of pages and its associated backing store. This is equivalent to punching a hole in the corresponding byte range of the backing store (see fallocate(2)). Subsequent accesses in the specified address range will see bytes containing zero.
那么取消映射/关闭/删除一个mmap
文件的最快路径是什么?
也许 mmap
与 MAP_PRIVATE
( like this ) 相同的区域,然后 munmap
它?
最佳答案
根据 this question , MADV_DONTNEED
正是这样做的:删除页面而不写回后台存储。
repopulating the memory contents from the up-to-date contents of the underlying mapped file
表示在 MADV_DONTNEED
之后加载将从后台存储重新加载。
MADV_DONTNEED
之前的所有脏页都没有提交到后台存储,因此将丢失。
总结:MADV_DONTNEED
丢弃所有映射页面(包括未提交到后台存储的脏页面)并保持后台存储不变。
关于c - 如何在 mmaped 内存中删除脏页并为快速 munmap 做准备?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54997052/