时长:大小9.46M
作者回复: pagecache和硬件关系不大,如果说pagecache一定要跟硬件关联起来的话,会有这几方面:一个page有多大,tlb有多大,cache有多大,物理内存多大,磁盘是ssd,hdd还是nvme。page的大小和物理内存的大小决定了pagecache的量,但是你会发现pagecache的回收机制其实是独立于这个量的,也就是,不论它有多少,active和inactive的替换逻辑是不变的。tlb大小和cache大小则影响了pagecache命中与否的性能,但是你会发现相比pagecache miss而言,tlb/cache miss几乎可以忽略不计,这是不同数量级的差异。磁盘介质又决定了pagecache的重要性,如果你的磁盘是hdd,那pagecache对应用的提升会非常明显;如果是nvme,那么pagecache miss后业务的性能下降也不会太明显;但是你会发现,不论磁盘介质是什么,pagecache如果命中的话,它的性能都是数量级的差异。 也就是说,pagecache自身的机制是独立与硬件的,不论你是什么样的硬件,都要尽量保障热数据在内存中,而冷数据则尽量不要占用内存,这就是pagecache机制的核心。 换一个角度而言,不论是x86还是arm,linux都要能工作,而能工作就是linux的本质,这个本质是我们想要讨论的。而不是讨论linux在arm上的工作和x86的工作会有什么差异。
作者回复: dropcache不会清理脏页,只会清理干净的页,所以如果你想清理所有的页的话,是需要在drop前先sync的。
作者回复: buffer可以理解为是一类特殊文件的cache,这类特殊文件就是设备文件,比如/dev/sda1, 这类设备文件的内容被读到内存后就是buffer。而cached则是普通文件的内容被读到了内存。你可以做一个试验,运行下面这个程序,然后观察/proc/meminfo里Buffers和Cached这两项的变化,你会发现增加的是前者。 #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define DEV "/dev/sda1" #define SIZE (1024 * 1024 * 1024) int main() { int fd = open(DEV, O_RDONLY); char *buf; int size; buf = malloc(SIZE); if (!buf) return -1; size = read(fd, buf, SIZE); printf("%d\n", size); while (1) { } return 0; }
作者回复: 是的。如果只读一遍后续再也不会用到,那确实没有必要还用pagecache,使用direct IO就可以了。而且超大文件读入到内存也会影响其他进程对内存的使用。
作者回复: 可以理解为是磁盘的缓存,但是它属于内存,不属于磁盘。
作者回复: 缓存io是指应用在读磁盘文件的时候会先经过缓存(内存),而且直接io则不经过缓存而直接与磁盘交互。
作者回复: 内核态和用户态是指进程的运行状态 并不能用来表示内存。 应用程序通过mmap系统调用返回的地址空间属于“用户空间”。 mmap的用户空间的地址对应的物理内存则是page cache,这是不同的概念。
作者回复: 因为swap得数据量往往较大,而且发生swap时往往是内存很紧张时,各种因素叠加会导致swap过程非常容易出问题。
作者回复: pagecache不是vfs模块来管理的,vfs只是提供了pagecache的一个使用接口,也就是标准io这种接口。pagecache是mm这个模块来管理的,回写和预读主要是涉及到mm和io子系统。
作者回复: 我在Mac上都是使用Vim+cscope来阅读内核源码,也是很方便的,最主要是这种方式在什么平台上都能用,通用性较好。 至于内核源码,可以紧跟upstream的源码来看,在你遇到一些疑惑时,你可以git blame来查看修改记录,修改记录里一般都会详细说明这么实现的原因。