如何将脏页放入mmaped内存中并准备快速munmap?

时间:2019-03-05 06:57:51

标签: c linux

我正在尝试为无交换系统实现文件支持的内存分配器。

对于每个新分配,我使用mkstemp创建一个临时文件作为后备存储,mmap将其创建为MAP_SHARED,以便在系统内存压力很高时允许将页面交换到该后备存储中。我想我已经完成了这一部分。

但是我在实施解除分配案件时遇到困难。

由于在重新分配时,后台存储的内容,驻留页面或脏页面的内容都不再重要,因此,最快的方法是删除并释放所有驻留页面并保持后台存储不变。但是我没有找到可以做到这一点的madvice标志。

MADV_DONTNEED似乎过多,因为它会将脏页提交到后存储。 (不正确,请参见下面的答案)

  

MADV_DONTNEED

     

成功执行MADV_DONTNEED操作后,将更改指定区域中的内存访问的语义:后续对该范围内的页面的访问将成功,但是将导致从最新的内容中重新填充内存内容。基础映射文件(用于共享文件映射,共享匿名映射以及基于shmem的技术,例如System V共享内存段)或用于匿名私有映射的按需填充零页面。

MADV_REMOVE似乎也过多,因为它不仅会删除常驻页面,而且还会删除后台存储本身。

  

MADV_REMOVE

     

释放给定范围的页面及其关联的后备存储。这等效于在后备存储的相应字节范围内打一个洞(请参见fallocate(2))。在指定地址范围内的后续访问将看到包含零的字节。

那么取消映射/关闭/删除mmap文件的最快步骤是什么?

也许mmapMAP_PRIVATElike this)再次相同,然后又munmap吗?

2 个答案:

答案 0 :(得分:1)

根据this questionreturn (x1 > x2) ? ((x1 > x3)? x1 : x3) : (x2 > x3) ? x2 : x3; 确实做到了这一点:删除页面而不写回后台存储。

子句if表示MADV_DONTNEED之后的加载将从后台存储重新加载。

repopulating the memory contents from the up-to-date contents of the underlying mapped file之前的所有脏页都没有提交到后备存储,因此将丢失。

总而言之:MADV_DONTNEED删除所有映射的页面(包括脏页面未提交到后备存储器),并按原样保留后备存储器。

Fun and informational video here

答案 1 :(得分:0)

在脏页上疯狂地MADV_DONTNEED不会放弃所做的更改。
我刚刚使用mmap / madvise MADV_DONTNEED / munmap编写了一个5GB的文件,最后2个步骤以2-4MB的块进行,并且该文件的创建没有一个错误。
但是MADV_DONTNEED对脏页没有影响。 munmap减少了该过程的RSS,但仍由Linux自行决定编写。