原文:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/
翻译:RobotCode俱乐部

现在来做一个测验。假设render程序的最后一个进程实例已经退出,会立即释放页面缓存中的scene.dat数据?人们经常这么认为的,但这不是一个好主意。你有没有想到,我们通常在一个程序中创建一个文件,然后退出,然后在另一个程序中要使用该文件。页面缓存也必须处理这种情况。所以内核为什么要删除页面缓存内容呢?请记住,磁盘比RAM慢5个数量级,因此页面缓存命中是一个巨大的胜利。只要有足够的空闲物理内存,缓存就应该被尽可能的使用。因此,它不依赖于特定的进程,而是一个系统范围的资源。如果你运行render进程一周后,发现scene.dat仍然被缓存,这太幸运了!这就是为什么内核缓存的大小会稳步上升,直到达到上限。这并不是因为操作系统是垃圾并占用你的RAM,这实际上是一种良好的行为,因为从某种程度上说,释放物理内存才是一种浪费。

由于页面缓存的存在,当程序调用write()写字节时,只需将其复制到页面缓存中,并将页面标记为dirty。磁盘I/O通常不会立即发生,因此你的程序不会阻塞等待磁盘。不利的一面是,如果计算机崩溃,您的写操作将永远无法完成,因此像数据库事务日志这样的关键文件必须调用fsync()立刻写入到磁盘(但是仍然需要担心驱动器控制器的缓存,也可能造成并不会立刻写入到物理磁盘)。另一方面,读取通常会阻塞程序,直到数据可用为止。内核使用预先加载技术来缓解这个问题,其中一个例子是提前读取,内核将几个页面预加载到页面缓存中,等待你的读取。你可以通过调整内核的一些选项来调整预先加载行为,可以控制顺序读取文件还是随机读取文件。Linux确实对内存映射文件进行预读,但我不确定Windows是否如此。最后,可以在Linux中使用O_DIRECT绕过页面缓存,或者在Windows中使用NO_BUFFERING绕过页面缓存,这是数据库软件经常做的事情。

文件映射可以是私有的或共享的。这是针对内存中的内容所做的更新:在私有映射中,更新不提交到磁盘或使其他进程可见,而在共享映射中,更新是可见的。内核使用页表项启用的写时复制机制来实现私有映射。在下面的例子中,render和render3d都私有映射了文件scene.dat。render然后写入它的虚拟内存区域中的映射文件:

上面所示的只读页表项并不意味着映射是只读的,它们只是在最后一刻共享物理内存的内核实现技巧。你可以看到“private”是多么的不恰当,只要记住它只适用于更新,读取不是私有的,也是共享的。这种设计的结果是,通过映射文件的虚拟页面可以反映出有其他程序对该文件做了更改一旦写时复制完成,其他人的更改将不再可见。内核不能保证这种行为,但它是在x86中得到的,(是通过硬件方式实现的?这里不太明白)从API的角度来看是有意义的。相比之下,共享映射仅仅映射到页面缓存,仅此而已。更新对于其他进程是可见的,并最终保存在磁盘中。最后,如果上面的映射是只读的,那么页面错误将触发段错误,而不是写入时的复制错误。

动态加载的库通过文件映射到程序的地址空间。这没有什么神奇的,它是同样的私有文件映射。下面的示例展示了两个运行实例部分地址空间中的文件映射,以及物理内存使用情况,以便我们将上述许多概念联系在一起。

关于内存基础的3部分系列文章到此结束。我希望这个系列是有用的,并为你提供了Linux内核内存管理的宏观机制。

--END

这3部分汇总如下:

RobotCode俱乐部:程序的内存布局(上)

RobotCode俱乐部:程序的内存布局(下)

RobotCode俱乐部:内核是如何管理内存的?(上)

RobotCode俱乐部:内核是如何管理内存的?(中)

RobotCode俱乐部:内核是如何管理内存的?(下)

RobotCode俱乐部:页面缓存(Page Cache)-内存和文件之间的那点事儿(上)

RobotCode俱乐部:页面缓存(Page Cache)-内存和文件之间的那点事儿(下)

由于本人水平有限,翻译必然有很多不妥的地方,欢迎指正。
同时,欢迎关注下方微信公众号,一起交流学习:)

读取文件慢_页面缓存(Page Cache)-内存和文件之间的那点事儿(下)相关推荐

  1. Linux读写缓存Page Cache

    一. 读写缓存Page Cache Linux对文件读写并不是每次都进行磁盘IO,而是将对应的磁盘文件缓存到内存上,之后对该文件的操作实际上也是对内存的读写. 缓存俗称页缓存(page cache), ...

  2. 文件缓存page cache

    address_space结构  host:指向当前 address_space 对象所属的文件 inode 对象 page_tree:用于存储当前文件的 页缓存 rb_boot i_mmap存储着共 ...

  3. cdr文件太大怎么转成小内存 CDR文件太大打不开怎么办

    使用cdr软件制作图形时,常常会将其制作成矢量图形.虽然矢量图形有着不失真.可任意放大等优点,但常会导致cdr文件过大.那么,cdr文件太大怎么转成小内存,CDR文件太大打不开怎么办?本文将会针对以上 ...

  4. 工作于内存和文件之间的页缓存, Page Cache, the Affair Between Memory and Files

    原文作者:Gustavo Duarte 原文地址:http://duartes.org/gustavo/blog/post/what-your-computer-does-while-you-wait ...

  5. syslog 向内存中缓存_漫谈缓存(Cache)、大规模芯片系统的存储层次结构优化以及开源仿真工具ZSim...

    这次的话题将从缓存开始,以一种易于理解的方式向大家呈现缓存的基本概念,然后拓展至大规模芯片系统的非均一访问延时的缓存访问问题,最后简要介绍一种缓存仿真工具--ZSim. 缓存的概念 处理器和内存之间存 ...

  6. linux缓存文件地址,如何遍历linux内核中的文件地址空间的页面缓存树(基数树)

    我从 Linux内核源代码中找到了它. struct file *file = filp_open("filename",O_RDONLY,0); struct address_s ...

  7. 启用tim无法访问文件夹_如何在三星手机上启用安全文件夹

    启用tim无法访问文件夹 The Secure Folder is a useful feature on Samsung devices that allows you to keep apps a ...

  8. 内存映射文件 写入 卡住_在Java中使用内存映射文件时检测(写入)失败

    内存映射文件 写入 卡住 内存映射文件是一个很好的并且经常被忽视的工具. 我不会在这里详细介绍它们的工作方式(使用 力 Google Luke!),但我将快速总结其优势: 操作系统提供的延迟加载和写入 ...

  9. python 知乎 合并 pdf_实例4:用Python提取不同PDF文件中的页面合并进新的PDF文件...

    公司船务部一个重要任务就是需要准备每单货物的发票,从系统导出发票时是默认存为一个PDF文档,在打印的时候,有多少个文件,就需要点多少次"打印".如果能够将当天的发票PDF档合并在一 ...

最新文章

  1. cs架构嵌入bs_CS与BS架构区别、比较、及现状与趋势分析
  2. 'avpicture_fill': 被声明为已否决
  3. 如何设计应用层协议(草稿)
  4. 想和产品大咖一对一沟通吗?
  5. DFS应用——遍历有向图+判断有向图是否有圈
  6. k8s中流量分离以及资源隔离实战
  7. C/C++队列与循环队列
  8. mysql运维机制_《MySQL运维内参》节选 | InnoDB日志管理机制(一)
  9. C# 延时小函数 很好用
  10. Oracle全文索引之四 维护
  11. Sequelize-nodejs-8-Transactions
  12. 浅谈UWB室内定位(三)_vortex_新浪博客
  13. lua.c:82:10: fatal error: readline/readline.h: 没有那个文件或目录
  14. oracle审计功能启动关闭
  15. Radius 协议介绍
  16. 某选煤厂智能智能化解决方案
  17. ibm是被联想收购了吗_联想集团收购IBM背后的苦
  18. JAVA8的一些写法
  19. 笔记本电脑更换固态硬盘
  20. 推荐系统组队学习之协同过滤

热门文章

  1. centos7 iptables 端口转发 保存_Linux 开发笔记《如何在CentOS 7上启动和启用Firewalld》...
  2. std::reserve和std::resize的区别
  3. 人工神经网络matlab啊6,MATLAB人工神经网络教程
  4. 公布自己的pods到CocoaPods trunk 及问题记录
  5. 自己动手构造编译系统:编译、汇编与链接2.1.3 符号表管理
  6. CentOS6.5搭建SVN服务器(Apache+SVN)
  7. 【转】 ID,ClientID和UniqueID
  8. mysql中blog数据_zp blog
  9. mapreduce分组统计_Mongodb的分组统计MapReduce
  10. linux脚本判断流程控制,Shell 脚本-6- 流程控制之判断分支