Linux 内核技术实战课
邵亚方
前蘑菇街技术专家,Linux Kernel 活跃贡献者
23704 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 26 讲
Linux 内核技术实战课
15
15
1.0x
00:00/00:00
登录|注册

02 基础篇 | Page Cache是怎样产生和释放的?

直接映射到用户地址空间
读取数据时反向操作
数据拷贝到内核缓冲区
写入用户缓冲区
初学内核开发者关注点
运维人员关注点
应用开发者关注点
推荐观测内存回收行为
Page Cache的透明特征
使用sar观测
内存回收行为
Page Reclaim
观测Dirty Pages
示例脚本演示
存储映射I/O
标准I/O
Memory-Mapped I/O
Buffered I/O
课后作业
课堂总结
观测内存回收行为
Page Cache释放方式
Page Cache观测
Page Cache产生过程
Page Cache产生方式
Page Cache生命周期

该思维导图由 AI 生成,仅供参考

你好,我是邵亚方。
上一讲,我们主要讲了“什么是 Page Cache”(What),“为什么需要 Page Cache”(Why),我们这堂课还需要继续了解一下“How”:也就是 Page Cache 是如何产生和释放的。
在我看来,对 Page Cache 的“What-Why-How”都有所了解之后,你才会对它引发的问题,比如说 Page Cache 引起的 load 飙高问题或者应用程序的 RT 抖动问题更加了然于胸,从而防范于未然。
其实,Page Cache 是如何产生和释放的,通俗一点的说就是它的“生”(分配)与“死”(释放),即 Page Cache 的生命周期,那么接下来,我们就先来看一下它是如何“诞生”的。

Page Cache 是如何“诞生”的?

Page Cache 的产生有两种不同的方式:
Buffered I/O(标准 I/O);
Memory-Mapped I/O(存储映射 I/O)。
这两种方式分别都是如何产生 Page Cache 的呢?来看下面这张图:
Page Cache产生方式示意图
从图中你可以看到,虽然二者都能产生 Page Cache,但是二者的还是有些差异的:
标准 I/O 是写的 (write(2)) 用户缓冲区 (Userpace Page 对应的内存),然后再将用户缓冲区里的数据拷贝到内核缓冲区 (Pagecache Page 对应的内存);如果是读的 (read(2)) 话则是先从内核缓冲区拷贝到用户缓冲区,再从用户缓冲区读数据,也就是 buffer 和文件内容不存在任何映射关系。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了Page Cache的产生和释放过程。通过生动的比喻和具体的示例,读者更加直观地了解了Page Cache的产生方式,包括标准I/O和存储映射I/O两种方式。同时,文章描述了Page Cache的“死亡”,即它是如何被释放的,以及如何观察内存回收行为。通过对脏页和回写到磁盘的监测,读者可以了解Page Cache的释放过程。文章还提到了一些与Page Cache相关的问题和监测方法,为读者进一步深入了解和应用Page Cache提供了参考。总的来说,本文内容详实,通俗易懂,适合对Page Cache感兴趣的读者阅读。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Linux 内核技术实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(29)

  • 最新
  • 精选
  • 邵亚方
    置顶
    课后作业答案: - 为什么第一次读写某个文件,Page Cache 是 Inactive 的? 第一次读取文件后,文件内容都是inactive的,只有再次读取这些内容后,才会把它放在active链表上,处于inactive链表上的pagecache在内存紧张是会首先被回收掉,有很多情况下文件内容往往只被读一次,比如日志文件,对于这类典型的one-off文件,它们占用的pagecache需要首先被回收掉;对于业务数据,往往都会读取多次,那么他们就会被放在active链表上,以此来达到保护的目的。 - 如何让它变成 Active 的呢? 第二次读取后,这些内容就会从inactive链表里给promote到active链表里,这也是评论区里有人提到的二次机会法。 - 在什么情况下 Active 的又会变成 Inactive 的呢? 在内存紧张时,会进行内存回收,回收会把inactive list的部分page给回收掉,为了维持inactive/active的平衡,就需要把active list的部分page给demote到inactive list上,demote的原则也是lru。 - 系统中有哪些控制项可以影响 Inactive 与 Active Page Cache 的大小或者二者的比例? min_free_kbytes会影响整体的pagecache大小;vfs_cache_pressure会影响在回收时回收pagecache和slab的比例; 在开启了swap的情况下,swappiness也会影响pagecache的大小;zone_reclaim_mode会影响node的pagecache大小;extfrag_threshold会影响pagecache的碎片情况。 - 对于匿名页而言,当产生一个匿名页后它会首先放在 Active 链表上,请问为什么会这样子?这是合理的吗? 这是不合理的,内核社区目前在做这一块的改进。具体可以参考https://lwn.net/Articles/816771/。
    2020-10-11
    1
    64
  • zwb
    第二次机会法,避免大量只读一次的文件涌入 active,在需要回收时又从 active 移动到 inactive lru 链表。场景比如编译内核。

    作者回复: 理解的很正确!

    2020-08-21
    3
    20
  • x-ray
    读这个确实需要对一些linux基础概念有一个了解。前几天刚读的时候,我连VFS都没有一个概念,读起来非常吃力,到第二章就看得云里雾里。这两天找了点视频把一些基础概念熟悉了下,今天再来看的时候,就感觉比较容易理解了。不过我有一个疑问,既然mmap映射的效率更高,为什么不都用这个呢?是因为标准IO无法像文件那样提前加载一块内存到PageCache吗?

    作者回复: mmap与标准io的选择要看具体的场景。很多情况下内存拷贝不会是瓶颈,比如说只写几个或者几百字节的情况下,所以使用哪种都可以;只有在内存拷贝成为瓶颈,比如读写大量文件内容的情况下,比如一次要读写几十上百M,mmap的优势才会提现出来。

    2020-09-15
    3
    9
  • Geek_162e2a
    应用开发者的视角 第一次读写文件,PageCache是inactive的,为什么要这样设计?可能内核底层是采用类似LRU链表的设计来管理PageCache, 如果单纯照搬LRU链表的设计的话,当读大文件的时候会将原本属于热点缓存的PageCache冲刷出去,导致性能波动,因此需要对PageCache进行分类,来避免这个问题,即新读入的文件先进入inactive区域

    作者回复: 理解的很准确 赞!

    2020-08-27
    2
    9
  • Geek_circle
    Memory-Mapped I/O(存储映射 I/O) 是否就是零拷贝的概念呢?

    作者回复: 可以这么理解,它是文件内容的零拷贝。

    2020-08-25
    7
  • 小白哥哥
    不认同邵老师对于pagecache产生原因的描述,应用程序调用了write,内核会根据fd当前的fpos计算出写文件操作的文件偏移,然后根据偏移去inode->mapping中找出对应的pagecache页,如果没有的话,分配一页,插入inode->mapping,然后把write调用中的buffer拷贝到pagecache中,这个过程并不会触发page fault。如果是mmap映射文件,然后直接对内存读写,才会触发page fault,进而驱动内核加载文件内容到对应的page cache中。

    作者回复: “这个过程并不会触发page fault”,除了这句话之外,你的其他理解是对的。 inode mapping中如果没有的话,内核会分配一个page,然后将write调用中的buffe拷贝到这个page 中,这个过程叫做pagein,它属于page fault的一种: major fault。你可以通过sar之类的工具来观察这个指标。

    2021-05-13
    6
    6
  • Geek_162e2a
    如何让它变成Active的呢?多读几次文件,达到系统设计的值后,此文件的PageCache会变成热点数据进入Active区域。 在什么情况Active会变成inactive的呢?热点文件太多,且此文件最近没有被读取过,自然就被挤出去了,静态资源服务器,可能会比较经常出现这种情况

    作者回复: 赞!

    2020-08-27
    3
  • 地下城勇士
    老师的图是用什么工具画的?感觉以后可以尝试一下

    作者回复: gliffy。chrome有插件。

    2020-08-25
    2
    3
  • 唐江
    什么地方讲了inactive 、active 是个数据结构链表啊!不是一个简单的数字吗

    作者回复: proc接口中提供给用户的只是具体的数据项,这些数据项对应到内核代码则是一些数据结构。对于inactive active这两项而言,他们对应内核代码里的lru list。

    2021-05-20
    2
  • Wade_阿伟
    老师您好,看了上面老师的讲述,对存储映射I/O和标准I/O有了一定的理解。但是系统一般什么时候使用存储映射I/O,什么时候使用标准I/O呢?

    作者回复: 标准io相对而言更方便些,在数据量不大的情况下可以使用;如果数据量较大,此时使用存储映射io会更好些。另外一个考虑因为是对内存的精细管理,如果需要管理,比如说把某些数据锁定在内存中,这个时候使用存储映射io更好些。

    2021-07-08
    1
收起评论
显示
设置
留言
29
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部