# 注意不同版本的free输出可能会有所不同
$ free
total used free shared buff/cache available
Mem: 8169348 263524 6875352 668 1030472 7611064
Swap: 0 0 0
本文目的用来区分free中最后一个指标:buffer和cache, 它们统称缓存,但在用途上存在差异。
区分
- Buffers 是内核缓冲区用到的内存,对应的是 /proc/meminfo 中的 Buffers 值。
- Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样,内核就可以把分散的读写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。
- Buffer 既可以用作“将要写入磁盘数据的缓存”,也可以用作“从磁盘读取数据的缓存”。
- Cache 是内核页缓存和 Slab 用到的内存,对应的是 /proc/meminfo 中的 Cached 与 SReclaimable 之和。
- Cached 是从磁盘读写文件的页缓存,也就是用来缓存从文件读写的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。
- SReclaimable 是 Slab 的一部分。Slab 包括两部分,其中的可回收部分,用 SReclaimable 记录;而不可回收部分,用 SUnreclaim 记录。
- Cache既可以用作“从文件读取数据的页缓存”,也可以用作“写文件的页缓存”。
工具
vmstat
监控系统整体的内存信息。
# 每隔1秒输出1组数据
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 7743608 1112 92168 0 0 0 0 52 152 0 1 100 0 0
0 0 0 7743608 1112 92168 0 0 0 0 36 92 0 0 100 0 0
- buff 和 cache 就是我们前面看到的 Buffers 和 Cache,单位是 KB。
- bi 和 bo 则分别表示块设备读取和写入的大小,单位为块 / 秒。因为 Linux 中块的大小是 1KB,所以这个单位也就等价于 KB/s。
cachestat
提供了整个系统缓存的读写命中情况。
# 每隔1秒输出一组数据,输出3组
$ cachestat 1 3
TOTAL MISSES HITS DIRTIES BUFFERS_MB CACHED_MB
2 0 2 1 17 279
2 0 2 1 17 279
2 0 2 1 17 279
- TOTAL ,表示总的 I/O 次数;
- MISSES ,表示缓存未命中的次数;
- HITS ,表示缓存命中的次数;
- DIRTIES, 表示新增到缓存中的脏页数;
- BUFFERS_MB 表示 Buffers 的大小,以 MB 为单位;
- CACHED_MB 表示 Cache 的大小,以 MB 为单位。
cachetop
提供了每个进程的缓存命中情况。
# 每隔5秒刷新一次数据
$ cachetop 5
11:58:50 Buffers MB: 258 / Cached MB: 347 / Sort: HITS / Order: ascending
PID UID CMD HITS MISSES DIRTIES READ_HIT% WRITE_HIT%
13029 root python 1 0 0 100.0% 0.0%
- 默认按照缓存的命中次数(HITS)排序,展示了每个进程的缓存命中情况。
- HITS:间隔时间内的缓存命中次数。
- MISSES:间隔时间内的缓存命中次数、未命中次数
- DIRTIES :间隔时间内新增到缓存中的脏页数。
sar
# 间隔1秒输出一组数据
# -r表示显示内存使用情况,-S表示显示Swap使用情况
$ sar -r -S 1
04:39:56 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
04:39:57 6249676 6839824 1919632 23.50 740512 67316 1691736 10.22 815156 841868 4
04:39:56 kbswpfree kbswpused %swpused kbswpcad %swpcad
04:39:57 8388604 0 0.00 0 0.00
04:39:57 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
04:39:58 6184472 6807064 1984836 24.30 772768 67380 1691736 10.22 847932 874224 20
04:39:57 kbswpfree kbswpused %swpused kbswpcad %swpcad
04:39:58 8388604 0 0.00 0 0.00
…
04:44:06 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
04:44:07 152780 6525716 8016528 98.13 6530440 51316 1691736 10.22 867124 6869332 0
04:44:06 kbswpfree kbswpused %swpused kbswpcad %swpcad
04:44:07 8384508 4096 0.05 52 1.27
- sar 的输出结果是两个表格,第一个表格表示内存的使用情况,第二个表格表示 Swap 的使用情况。其中,各个指标名称前面的 kb 前缀,表示这些指标的单位是 KB。
- kbcommit,表示当前系统负载需要的内存。它实际上是为了保证系统内存不溢出,对需要内存的估计值。
- %commit,就是这个值相对总内存的百分比。
- kbactive,表示活跃内存,也就是最近使用过的内存,一般不会被系统回收。
- kbinact,表示非活跃内存,也就是不常访问的内存,有可能会被系统回收。
linux相关
/dev/null
- 在 Linux 上,从驱动程序到设备的所有内容都可以作为文件进行访问。/dev/ 是包含所有物理和虚拟设备的目录。例如,/dev/sda 可能是您的主硬盘驱动器,/dev/sdb 可能是您现在正在使用的笔记本驱动器的文件。这就是您在 Linux 中访问设备的方式。除了这些物理设备(如硬盘驱动器)之外,Linux还具有虚拟设备。虚拟设备是类似于物理设备的设备,但实际上仅以软件形式存在。应用程序可以从这些设备获取数据,但这些数据(而不是来自物理设备)来自操作系统本身。
- /dev/null 在 Linux 中是一个 void,它会吸收任何输入,并且不返回任何内容。大多数情况下,管理员使用if来转储无用的数据,在其中输出,这样它就不会占用系统内存和处理能力。甚至可以通过将无用的文件直接移动到 /dev/null/ 来删除它们。
缓存命中率
- 缓存命中率,是指直接通过缓存获取数据的请求次数,占所有数据请求次数的百分比。
- 命中率越高,表示使用缓存带来的收益越高,应用程序的性能也就越好。
- 在关注缓存命中率时,要同时关注每秒实际读取的数据大小。
- HITS 代表缓存的命中次数,每次命中能读取一页,即4KB大小。
- 在固定时间间隔内,如果缓存命中率特别高,但还是读写速度很慢,需要关注每秒实际读取的数据大小(命中次数很少是直接证明)。这时候可能是因为为系统调用设置了直接 I/O 的标志,绕过了系统缓存。
每秒实际读取的数据大小 = HITS * 4K / time_interval = xx KB/s
脏页
Linux内核由于存在page cache, 一般修改的文件数据并不会马上同步到磁盘,会缓存在内存的page cache中,我们把这种和磁盘数据不一致的页称为脏页,脏页会在合适的时机同步到磁盘。为了回写page cache中的脏页,需要标记页为脏(dirty)。