PageCache
PageCache一页有4KB左右。
当需要写入磁盘的时候,若每写入一个字节数据就调用IO,这样效率就太低了,所以在操作系统的底层会有一个缓冲区,叫做PageCache,当PageCache中存满了,再写入磁盘,这样大大减少了磁盘IO的次数。

上图是写入磁盘的过程,我们使用MMap或者是FileChannel都会经过PageCache层。例如,我们使用FileChannel的时候,先写进DirectByteBuffer中,当buffer中数据满的时候,先写入PageCache,再写入磁盘(操作系统完成)。
同样的,读取数据也是一样的,将数据以及其邻近的一些数据读取到PageCache。
例如,当用户发起一个 fileChannel.read(4kb) 之后,实际发生了两件事
- 操作系统从磁盘加载了 16kb 进入 PageCache,这被称为预读
- 操作通从 PageCache 拷贝 4kb 进入用户内存
最终我们在用户内存访问到了 4kb,为什么顺序读快?很容量想到,当用户继续访问接下来的[4kb,16kb]的磁盘内容时,便是直接从 PageCache 去访问了。试想一下,当需要访问 16kb 的磁盘内容时,是发生4次磁盘 IO 快,还是发生1次磁盘 IO+4 次内存 IO 快呢?答案是显而易见的,这一切都是 PageCache 带来的优化。
DirectIO
虽然PageCache很好,但是我们有时候并不希望使用PageCache。
当我们有时候进行随即读的时候,其实有时候并不需要PageCache的预读。
PageCache是操作系统层面上的概念,用很难干预,User BufferCache显然比PageCache要可控的多。
当操作系统回收 PageCache 内存的速度低于应用写缓存的速度时,会影响磁盘写入的速率,直接表现为写入 RT 增大,这被称之为“毛刺现象”。
而DirectIO可以绕过PageCache。