2-PageCachechan产生释放及优化( 三 )


运行该脚本前你要确保系统中有足够多的 free 内存(避免内存紧张产生回收行为),最终的测试结果是这样的:
File size 1048576KB, File Cache increased 1048648KB
在创建一个文件的过程中,代码中 /proc/ 里的(file)活动文件 和 (file) 非活动文件 这两项会随着文件内容的增加而增加,它们增加的大小跟文件大小是一致的 如果你观察得很仔细的话,你会发现增加的 Page Cache 是 (File) 这一项
用一张图简单描述下这个过程
首先往用户缓冲区 (这是Page) 写入数据,然后中的数据拷贝到内核缓冲区(这是Page),如果内核缓冲区中还没有这个 Page,就会发生 Page Fault(缺页异常) 会去分配一个 Page,拷贝结束后该Page 是一个 Dirty Page(脏页),然后该 Dirty Page 中的内容会同步到磁盘,同步到磁盘后,该Page 变为 Clean Page 并且继续存在系统中 。
可以将Alloc Page 理解为 Page Cache 的“诞生”,
将 Dirty Page 理解为Page Cache 的婴幼儿时期(最容易生病的时期),
将 Clean Page 理解为 Page Cache的成年时期(在这个时期就很少会生病了) 。
但是请注意,并不是所有人都有童年的, 如果是读文件产生的 Page Cache,它的内容跟磁盘内容是一致的,所以它一开 始是 Clean Page 成年时期 除非改写了里面的内容才会变成 Dirty Page(返老还童)
为了提前发现或者预防婴幼儿 时期的 Page Cache 发病,我们也需要一些手段来观测它:
$ cat /proc/vmstat | egrep "dirty|writeback"nr_dirty 40nr_writeback 2
如上所示, 表示当前系统中积压了多少脏页,
则表示有多少脏页正 在回写到磁盘中,他们两个的单位都是 Page(4KB)
通常情况下,小朋友们(Dirty Pages)聚集在一起(脏页积压)不会有什么问题 特殊情况下Dirty Pages 如果积压得过多,在某些情况下也会容易引发问题 后面章节介绍
的释放
你可以把 Page Cache 的回收行为 (Page ) 理解为 Page Cache 的“自然死 亡” 。我们知道,服务器运行久了后,系统中 free 的内存会越来越少,用 free 命令来查看,*大部分都会是 used 内存或者 buff/cache 内存 *
$ free -gtotal used free shared buff/cache availableMem: 125 41 6 0 79 82Swap: 0 0 0
free 命令中的 buff/cache 中的这些就是“活着”的 Page Cache, 那它们什么时候会“死 亡”(被回收)呢?我们来看一张图:
应用在申请内存的时候,即使没有 free 内存,只要还有足够可回收的 ,就可以通过回收 Page Cache 的方式来申请到内存,回收的方式主要是两种:直接回收和后台回收 。
观察 Page Cache 直接回收 和后台回收最简单方便的方式是使用 sar:
$ sar -B 102:14:01 PM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscan02:14:01 PM 0.14 841.53 106745.40 0.00 41936.13 0.00 002:15:01 PM 5.84 840.97 86713.56 0.00 43612.15 717.81 002:16:01 PM 95.02 816.53 100707.84 0.13 46525.81 3557.90 002:17:01 PM 10.56 901.38 122726.31 0.27 54936.13 8791.40 002:18:01 PM 108.14 306.69 96519.75 1.15 67410.50 14315.98 3102:19:01 PM 5.97 489.67 88026.03 0.18 48526.07 1061.53 0
借助上面这些指标,你可以更加明确地观察内存回收行为,下面是这些指标的具体含义:
/s : (后台回收线程) 每秒扫描的 page 个数 。/s:在内存申请过程中每秒直接扫描的 page 个数 。
/s: 扫描的 page 中每秒被回收的个数 。%vmeff: /(+), 回收效率,越接近 100 说明系统越安全,越接近 0 说明系统内存压力越大
这几个指标也是通过解析 /proc/ 里面的数据来得出的,对应关系如下:
Linus 对 Linux设计的第一原则是“never break the user space” 。