Linux页面缓存 - 从内核中的页面缓存中删除页面

时间:2015-05-02 05:55:18

标签: linux linux-kernel page-caching

我的问题是这个How to manipulate page cache in Linux?

的扩展

我试图做一个旨在限制每个文件使用的页面缓存大小的小项目。我使用的方法如下 -

  1. 在页面指针添加到页面缓存时保持页面指针的kfifo队列。
  2. add_to_page_cache_lru()中添加一个钩子,看看文件的基数树(address_space)的大小是否大于预定大小,然后从fifo队列中选择一个受害者,从页面缓存中删除页面。
  3. 我使用 delete_from_page_cache() try_to_unmap()这些功能从页面缓存中逐出页面,然后是 put_page()发布页面。
  4. 我希望这段代码可以释放页面并释放内存,但这似乎不会发生。例如,如果我读取大小为25MB的文件并且我将此文件的页面缓存大小限制为512页(2MB),那么我希望在可用内存中看到只有2MB的更改(免费-m)。 我所看到的是完整的25MB被吃掉并显示在免费命令中。

    我还应该做些什么来确保满足我的要求?我还没有想过脏页面,因为我甚至无法让它适用于读取(cat the file)。任何指针都会有所帮助。

    P.S。 - 我在这个项目中使用linux 4.0。

4 个答案:

答案 0 :(得分:2)

我建议不要进行任何更改,因为内核随附的LRU / MRU缓存算法非常有效。

首先,内核不维护页面缓存中所有文件的主列表,因为它不需要此类信息。相反,给定一个索引节点,您可以查找关联的页面缓存页面,反之亦然。

每个页面缓存结构页面 page_mapping()将返回属于结构的宿主成员的结构 address_space address_space 标识拥有结构的inode ,然后从中获取inode编号和设备。

在询问该程序时,可以使用cgroups:

创建一个名为group1的cgroup,其内存限制为50GB(例如,支持其他限制,例如CPU,在示例中也提到了CPU):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

然后,如果您的应用程序已经在运行,请将程序放入此cgroup:

cgclassify -g memory,cpu:group1 $(pidof your program)

或在此cgroup中执行程序:

cgexec -g memory,cpu:group1 your_app_name


如何在Linux下清除缓冲区/页面缓存(磁盘缓存)

什么是内存缓存

为了加快操作速度并减少磁盘I / O,内核通常会进行尽可能多的缓存

如何使用/ proc / sys / vm / drop_caches清除内存缓存

1。为了清除PageCache仅运行:

# sync; echo 1 > /proc/sys/vm/drop_caches

2。为了清除牙科(也称为目录缓存)和inode,请运行:

# sync; echo 2 > /proc/sys/vm/drop_caches

3。为了清除PageCache,运行dentries和inode:

# sync; echo 3 > /proc/sys/vm/drop_caches

注意:- 如上述3条命令所示,从sync命令开始是可选的。 sync命令允许内核将尽可能多的脏缓存页面写入磁盘(以最大程度地减少可丢弃的数据缓存页面的数量)

页面缓存是读取文件后保留的内存。 Linux内核更喜欢保留未使用的页面缓存,前提是假设一次读取的文件很可能在不久的将来再次读取

牙科 inode_cache 是读取目录/文件属性(例如open()和stat())后保留的内存。 dentry在所有文件系统中都很常见,但是inode_cache是​​基于每个文件系统的。 Linux内核希望保留此信息,前提是在不久的将来再次需要它,从而避免了磁盘IO。

答案 1 :(得分:0)

您可能不仅需要 delete_from_page_cache() + try_to_unmap() + put_page() ...

>

查看 shrink_page_list()的行为方式,包括对 page_check_references()的检查:

更多信息: How to unmap struct page from all PTEs mapping it

答案 2 :(得分:0)

我认为您正在与文件系统作斗争。

  1. 如果要添加可加载模块linux缓存子系统,而fs缓存系统不知道这一点。

    将ftrace与函数图一起使用以跟踪内核空间中的函数。会给更多 了解哪些函数被调用。

  2. cgroup是扩展或Linux缓存的更好模块。无论您要达到什么目标。

我不确定确切的原因,但是以上信息可以帮助您找出答案。

答案 3 :(得分:-2)

也许盯着释放(清空)缓存将有助于您的调试。

要直接回答标题问题,请参阅https://unix.stackexchange.com/questions/87908/how-do-you-empty-the-buffers-and-cache-on-a-linux-system

关于以下命令的讨论:

cut