《Linux性能优化实战》笔记(九)—— 查看内存使用情况、Buffer和Cache的区别

60 篇文章 13 订阅
10 篇文章 3 订阅

一、 查看内存使用情况

1. free 工具

free 显示的是整个系统的内存使用情况(默认以字节为单位):

两行分别是物理内存 Mem 和 Swap 的使用情况,而六列中,每列数据的含义分别为:

  • 第一列,total 是总内存大小
  • 第二列,used 是已使用内存的大小,包含了共享内存
  • 第三列,free 是未使用内存的大小
  • 第四列,shared 是共享内存的大小
  • 第五列,buff/cache 是缓存和缓冲区的大小
  • 最后一列,available 是新进程可用内存的大小(未使用内存+可回收的缓存)

 

2. top或ps

查看进程的内存使用情况,可以用 top 或者 ps 等工具。

top 输出界面的顶端,也显示了系统整体的内存使用情况,这些数据跟 free 类似。下面几列数据,VIRT、RES、SHR 以及 %MEM,包含了进程最重要的几个内存使用情况:

  • VIRT 是进程虚拟内存的大小,只要是进程申请过的内存,即便还没有真正分配物理内存,也会计算在内。
  • RES 是常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括 Swap 和共享内存。
  • SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。
  • %MEM 是进程使用物理内存占系统总内存的百分比。

除了这些基本信息,在查看 top 输出时,你还要注意两点。

  • 第一,虚拟内存通常并不会全部分配物理内存。从上面的输出,你可以发现每个进程的虚拟内存都比常驻内存大得多。
  • 第二,共享内存 SHR 并不一定是共享的,比方说,程序的代码段、非共享的动态链接库,也都算在 SHR 里。当然,SHR 也包括了进程间真正共享的内存。所以在计算多个进程的内存使用时,不要把所有进程的 SHR 直接相加得出结果。

 

二、 free 数据的来源

buffer和cache的中文翻译非常像,它们有什么相同和不同呢?用 man 命令查询 free 的文档,就可以找到对应指标
的详细说明。

buffers:Memory used by kernel buffers (Buffers in /proc/meminfo)
cache:Memory used by the page cache and slabs (Cached and SReclaimable)
buff/cache:Sum of buffers and cache

  • Buffers 是内核缓冲区用到的内存,对应的是 /proc/meminfo 中的 Buffers 值。
  • Cache 是内核页缓存和 Slab 用到的内存,对应的是 /proc/meminfo 中的 Cached 与SReclaimable 之和。

这里的说明告诉我们,这些数值都来自 /proc/meminfo,但更具体的 Buffers、Cached 和 SReclaimable 的含义,还是没有说清楚。我们还得继续查 proc 文件系统,获取它们的详细定义。执行 man proc ,你就可以得到 proc 文件系统的详细文档。

  • Buffers 是对原始磁盘块的临时存储,用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样就可以把分散的写集中起来,统一优化磁盘的写入,比如把多次小的写合并成单次大的写等等。
  • Cached 是从磁盘读取文件的页缓存,用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。
  • SReclaimable 是 Slab 的一部分。Slab 包括两部分,其中的可回收部分,用SReclaimable 记录;而不可回收部分,用 SUnreclaim 记录。

 

三、案例实践

模拟磁盘及文件IO,观察buffer与cache情况。

# 清理系统缓存:清理文件页、目录项、Inodes等各种缓存
echo 3 > /proc/sys/vm/drop_caches

1. 模拟文件写

输出界面里, 内存部分的 buff 和 cache ,以及 io 部分的 bi 和 bo 就是我们要关注的重点:

  • buff 和 cache 就是我们前面看到的 Buffers 和 Cache,单位是 KB。
  • bi 和 bo 则分别表示块设备读取和写入的大小,单位为块 / 秒。因为 Linux 中块的大小
  • 是 1KB,所以这个单位也就等价于 KB/s

第二个终端执行 dd 命令,通过读取随机设备,生成一个 500MB 大小的文件:

dd if=/dev/urandom of=/tmp/file bs=1M count=500

观察 Buffer 和 Cache 的变化情况:发现在 dd 命令运行时,Cache 在不停地增长,而Buffer 基本保持不变。

再进一步观察 I/O 的情况,你会看到

  • 在 Cache 刚开始增长时,块设备 I/O 很少,bi 只出现了一次 488 KB/s,bo 则只有一次 4KB。而过一段时间后,才会出现大量的块设备写,比如 bo 变成了 122880。
  • 当 dd 命令结束后,Cache 不再增长,但块设备写还会持续一段时间,并且,多次 I/O写的结果加起来,才是 dd 要写的 500M 的数据。

为什么前面文档上说 Cache 是文件读的页缓存,现在写文件也有它的份?这个疑问,我们暂且先记下来,接着再来看另一个磁盘写的案例。两个案例结束后,我们再统一进行分析。
 

2. 模拟文件写

下面的命令对环境要求很高,需要你的系统配置多块磁盘,并且磁盘分区 /dev/sdb1 还要处于未使用状态。如果你只有一块磁盘,千万不要尝试,否则将会对你的磁盘分区造成损坏。如果你的系统符合标准,就可以继续在第二个终端中,运行下面的命令。清理缓存后,向磁盘分区 /dev/sdb1 写入 2GB 的随机数据:

# 首先清理缓存
echo 3 > /proc/sys/vm/drop_caches
# 然后运行dd命令向磁盘分区/dev/sdb1写入2G数据
dd if=/dev/urandom of=/dev/sdb1 bs=1M count=2048

再回到终端一,观察内存和 I/O 的变化情况:

虽然同是写数据,写磁盘跟写文件的现象还是不同的。写磁盘时(bo 大于 0 时)Buffer 和 Cache 都在增长,但显然 Buffer 的增长快得多。这说明,写磁盘用到了大量的 Buffer,这跟在文档中查到的定义是一样的。

对比两个案例,我们发现,写文件时会用到 Cache 缓存数据,而写磁盘则会用到 Buffer 来缓存数据。所以,回到刚刚的问题,虽然文档上只提到,Cache 是文件读的缓存,但实际上,Cache 也会缓存写文件时的数据。
 

3. 模拟文件读

运行下面的命令。清理缓存后,从文件 /tmp/file 中,读取数据写入空设备:

# 首先清理缓存
echo 3 > /proc/sys/vm/drop_caches
# 运行dd命令读取文件数据
dd if=/tmp/file of=/dev/null

再回到终端一,观察内存和 I/O 的变化情况:

你会发现读取文件时(也就是 bi 大于 0 时),Buffer 保持不变,而Cache 则在不停增长。这跟我们查到的定义“Cache 是对文件读的页缓存”是一致的。

 

4. 模拟磁盘读

清理缓存后,从磁盘分区 /dev/sda1 中读取数据,写入空设备:

# 首先清理缓存
echo 3 > /proc/sys/vm/drop_caches
# 运行dd命令读取文件
dd if=/dev/sda1 of=/dev/null bs=1M count=1024

再回到终端一,观察内存和 I/O 的变化情况:

你会发现读磁盘时(也就是 bi 大于 0 时),Buffer 和 Cache 都在增长,但显然 Buffer 的增长快很多。这说明读磁盘时,数据缓存到了 Buffer 中。

四、 文件与磁盘的区别

看完前面,你有没有好奇上面所说的文件和磁盘到底有什么区别?读写文件不是最终会落到磁盘吗,linux中的磁盘不也是文件吗?补充一个后面的答疑:

磁盘是一个存储设备(块设备),可以被划分为不同的磁盘分区。在磁盘或者磁盘分区上,还可以再创建文件系统,并挂载到系统的某个目录中。这样,系统就可以通过这个挂载目录,来读写文件。换句话说,磁盘是存储数据的块设备,也是文件系统的载体。所以,文件系统确实还是要通过磁盘,来保证数据的持久化存储。

你在很多地方都会看到这句话, Linux 中一切皆文件。换句话说,你可以通过相同的文件接口,来访问磁盘和文件(比如 open、read、write、close 等)。

我们通常说的“文件”,其实是指普通文件;而磁盘或者分区,则是指块设备文件。

可以执行 “ls -l < 路径 >” 查看它们的区别。如果不懂 ls 输出的含义,执行 man ls 命令,以及 info ‘(coreutils) ls invocation’ 命令,就可以查到了。

在读写普通文件时,I/O 请求会首先经过文件系统,由文件系统负责与磁盘进行交互。在读写块设备文件时,会跳过文件系统,直接与磁盘交互,也就是所谓的“裸I/O”。两种读写方式使用的缓存不同:文件系统管理的缓存,其实就是 Cache 的一部分;而裸磁盘的缓存,用的正是 Buffer。

 

五、 小结

通过文档和实验,我们简单概括Buffer和Cache的区别:

  • Buffer 既可以用作“将要写入磁盘数据的缓存”,也可以用作“从磁盘读取数据的缓存”。
  • Cache 既可以用作“从文件读取数据的页缓存”,也可以用作“写文件的页缓存”。

也就是说,Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们都既会用在读请求中,也会用在写请求中。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值