由于我们开发的程序要运行的话一般都在 linux 上运行,以下以 linux 为例来讲解
Page Cache 的本质是由 Linux 内核管理的内存区域。通过 mmap(memory map) 以及 buffered io?将文件读取到内存空间实际上都是读取到 Page Cache 中。mmap 是通过指针操作的方式绕过了内核态直接操作?Page Cache。
通过读取 /proc/meminfo 文件,能够实时获取系统内存情况
Page Cache =
Buffers + Cached + SwapCached =
Active(file) + Inactive(file) + Shmem + SwapCached
page 是内存管理分配的基本单位, Page Cache 由多个 page 构成。
page 在操作系统中通常为 4KB 大小,而 Page Cache 的大小则为 4KB 的整数倍。
在 Page Cache 中,Active(file)+Inactive(file) 是 File-backed page(与文件对应的内存页),是我们需要关注的部分。因为平时用的 mmap() 内存映射方式和 buffered IO来消耗的内存就属于这部分。
但并不是所有 page 都被组织为 Page Cache。
Linux 系统上供用户可访问的内存分为两个类型,即:
这是因为从磁盘中加载到内存的数据不仅仅放在 Page Cache 中,还放在 buffer cache 中。
通过 Direct IO 技术的磁盘文件就不会进入 Page Cache 中。
在 2.4 版本内核之后,两块缓存近似融合在了一起:如果一个文件的页加载到了 Page Cache,那么同时 buffer cache 只需要维护块指向页的指针就可以了。只有那些没有文件表示的块,或者绕过了文件系统直接操作(如dd命令)的块,才会真正放到 buffer cache 里。
因此,现在 Page Cache,基本上都同时指 Page Cache 和 buffer cache 两者。
如果数据能够在内存中进行缓存,那么下一次访问就不需要通过磁盘 I/O 了,直接命中内存缓存即可。
由于内存访问比磁盘访问快很多,因此加快数据访问是 Page Cache 的一大优势。
得益于 Page Cache 的缓存以及预读能力,而程序又往往符合局部性原理,因此通过一次 I/O 将多个 page 装入 Page Cache 能够减少磁盘 I/O 次数, 进而提高系统磁盘 I/O 吞吐量。
page cache 也有其劣势,最直接的缺点是需要占用额外物理内存空间,物理内存在比较紧俏的时候可能会导致频繁的 swap 操作,最终导致系统的磁盘 I/O 负载的上升。
Page Cache 的另一个缺陷是对应用层并没有提供很好的管理 API,几乎是透明管理。
应用层即使想优化 Page Cache 的使用策略也很难进行。
因此一些应用选择在用户空间实现自己的 page 管理,而不使用 page cache,例如 MySQL InnoDB 存储引擎以 16KB 的页进行管理。
Page Cache 最后一个缺陷是在某些应用场景下比 Direct IO 多一次磁盘读 IO 以及磁盘写 IO。
Direct IO 即直接 IO。
缓存文件 IO:用户空间要读写一个文件并不直接与磁盘交互,而是中间夹了一层缓存,即 page cache;
直接文件 IO:用户空间读取的文件直接与磁盘交互,没有中间 page cache 层;
其他所有技术中,数据至少需要在内核空间存储一份,但是在 Direct IO 技术中,数据直接存储在用户空间中,绕过了内核。
Direct IO 的读写特点:
参考文档
https://blog.csdn.net/weixin_63769882/article/details/130594817