是否可以通过用户编程控制页面调出和页面调入?如果是,那么如何?

时间:2016-04-26 06:28:41

标签: c memory memory-management linux-kernel

我的问题如下:

mmap (内存映射)将文件放入虚拟内存空间。 当我第一次使用指针访问文件的第一个字节时,操作系统将尝试访问内存中的数据,但它会失败并引发页面错误,因为现在数据不存在于内存中。因此操作系统会将数据从磁盘交换到内存中。最后,我的访问将成功。

(问题即将来临) 当我修改数据(内存中)并写回磁盘文件时,我怎么能释放物理内存供其他人使用,但是保留虚拟内存以便根据需要将数据提取回内存? 这听起来像操作系统知道内存耗尽的页面输出和页面调整行为,它会将LRU(或类似的东西)内存页面交换到磁盘(交换文件)并释放物理内存用于其他进程,以及根据需要将被驱逐的数据提取回内存。但这种机制由操作系统控制。

由于某些原因,我需要自己控制页面调出和页面调整行为。那我该怎么办?破解内核?

2 个答案:

答案 0 :(得分:1)

您可以使用madvise系统调用。它的行为受advice参数的影响;有很多建议选择,应根据申请的具体情况选择最佳建议。

标志MADV_DONTNEED意味着应该无条件地释放给定范围的物理支持帧(即,被分页)。也:

  

成功MADV_DONTNEED操作后,语义为     更改指定区域中的内存访问:后续     对范围内页面的访问将成功,但会产生     从最新的重新填充内存内容     底层映射文件的内容(用于共享文件)     映射,共享匿名映射和基于shmem     诸如System V共享内存段之类的技术)或零     匿名私有映射的按需填充页面。

如果你绝对确定它会非常长,直到你再次访问同一个位置,这可能会很有用。

然而,可能没有必要强制内核实际页面输出;相反,另一种可能性是,如果您按顺序访问映射,则使用madviseMADV_SEQUENTIAL告诉内核您主要按顺序访问内存映射:

  

按顺序排列页面引用。 (因此,可以提前积极地读取给定范围内的页面,并且可以在访问它们后立即释放它们。)

MADV_RANDOM

  

以随机顺序预期页面引用。 (因此,预读可能没有通常那么有用。)

这些并不像明确调用MADV_DONTNEED页面那样具有攻击性。 (当然你也可以将它们与MADV_DONTNEED结合起来)

在最近的内核版本中,还有the MADV_FREE flag可以懒得释放页面框架;如果有足够的内存可用,它们将保持映射状态,但如果内存压力增大,内核将回收它们。

答案 1 :(得分:0)

你可以用mlock + munlock来锁定/解锁页面。这将使您可以控制被换出的页面。

您需要具有CAP_IPC_LOCK功能才能执行此操作。