C语言 是否可以通过用户编程来控制分页和分页?如果是,那么如何



我的问题如下:

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

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

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

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

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

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

如果您绝对确定再次访问同一位置之前需要很长时间,这可能会很有用。

但是,可能没有必要强制内核实际分页;相反,如果您按顺序访问映射,另一种可能性是将madviseMADV_SEQUENTIAL一起使用,以告诉内核您将主要按顺序访问内存映射:

期望按顺序排列页面引用。 (因此,可以主动提前阅读给定范围内的页面,并且可以在访问后立即释放。

MADV_RANDOM

期望页面引用按随机顺序排列。 (因此,提前阅读可能不如平时有用。

这些并不像明确调用MADV_DONTNEED来分页那样激进。(当然,您也可以将这些与MADV_DONTNEED结合使用)


在最近的内核版本中,还有 MADV_FREE 标志,它将延迟释放页面框架;如果有足够的内存可用,它们将保持映射,但如果内存压力增加,它们将被内核回收。

您可以欺骗mlock+mlock来锁定/解锁页面。 这将使您能够控制要换出的页面。

但是,您需要具有CAP_IPC_LOCK能力才能执行此操作。

最新更新