查看当前系统的内存使用情况时,我们最常使用free来查看,如下
root@7bc18553126f:/# free -h
total used free shared buff/cache available
Mem: 1.9G 374M 465M 258M 1.1G 1.3G
Swap: 1.0G 62M 961M
root@7bc18553126f:/#
Mem就是内存相关信息,而Swap就是内存和磁盘的转换相关情况
具体字段含义如下:
字段MemSwaptotal系统总的可用物理内存系统总的可用交换内存userd已经被使用的物理内存已经被使用的交换内存free空闲的物理内存空闲的交换内存shared被共享使用的物理内存N/Abuff/cachebuffer和cache使用的物理内存之和N/Aavailable可用的物理内存大小N/A其中:
free和available的区别就是:
free就是真正尚未被使用的物理内存大小;
available就是从应用程度的角度看到的可用内存数量。(Linux内核为了提升磁盘操作的性能,会消耗一部分内存去缓存磁盘数据,就是buff/cache。当应用程序没有足够的free内存可用,内核就会从buffer和cache中回收一部分内存来满足应用程序的需求。理论上来说available=free+buffer+cache,但实际上available会小于三者之和,因为不是所有的free/buffer都能释放)
free的输出参数比较少,具体内容也比较好理解,但是buff/cache就比较难理解了,下面我们通过实验的方式来说明这两个参数。
1.Cache测试 1.1 使用dd命令在Ubuntu_docker容器中测试文件写出# if(读取随机设备) of(写入到/tmp/file中),每次1M,执行2000次,最终生成一个2000M的/tmp/file文件
root@7bc18553126f:/# dd if=/dev/urandom of=/tmp/file bs=1M count=2000
2000+0 records in
2000+0 records out
2097152000 bytes (2.1 GB, 2.0 GiB) copied, 6.46847 s, 324 MB/s
1.2 vmstat观察
root@7bc18553126f:/# vmstat -w 1
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 64248 947476 100104 608552 0 0 26 43 0 91 1 1 98 0 0
0 0 64248 947508 100104 608564 0 0 0 0 714 1257 1 0 99 0 0
1 0 64248 947508 100104 608564 0 0 0 0 563 965 0 1 99 0 0
1 0 64248 806672 100120 748280 0 0 80 49152 1062 1001 0 12 87 0 0
2 0 64248 478284 100156 1075892 0 0 0 327680 1635 926 0 27 73 0 0
1 0 64248 145172 100168 1408272 0 0 0 311296 1615 860 0 27 73 0 0
1 0 64248 30476 100104 1523332 0 0 0 310388 1840 1247 0 28 72 0 0
1 0 64248 33388 100104 1519812 0 0 0 344064 2574 1434 0 30 70 0 0
1 0 64248 44288 100116 1509880 0 0 0 367708 2541 1557 0 29 61 10 0
1 0 64248 69732 100116 1485648 0 0 0 245760 2311 1577 0 29 72 0 0
0 0 64248 63136 100116 1492180 0 0 12 0 535 862 0 1 99 0 0
0 0 64248 62884 100116 1492168 0 0 0 0 507 879 0 1 99 0 0
0 0 64248 62916 100116 1492136 0 0 0 0 492 861 0 1 99 0 0
0 0 64248 63388 100116 1492120 0 0 0 0 855 1537 1 1 99 0 0
可以看到,io中bo(输出)刚开始还很小(bo=49152),后面一下子升高到327680,后来不断持续,一直到245760,后面到0,这时说明2000M的内容已经全部写出完毕。
而这时memory中的buff一直没有增长,cache则一直在增长。
1.3 Ubuntu测试文件读取# /tmp/file还是1.1中写出的文件
root@7bc18553126f:/# dd if=/tmp/file of=/dev/null
4096000+0 records in
4096000+0 records out
2097152000 bytes (2.1 GB, 2.0 GiB) copied, 3.7903 s, 553 MB/s
1.4 vmstat观察文件读取
root@7bc18553126f:/# vmstat -w 1
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 67344 957328 100228 604824 0 0 26 51 2 92 1 1 98 0 0
2 0 67344 957336 100228 604924 0 0 0 0 484 840 0 0 99 0 0
0 0 67344 957084 100228 604924 0 0 0 0 496 896 0 1 99 0 0
0 0 67344 957332 100228 604924 0 0 0 0 642 1099 0 1 99 0 0
1 0 67344 809916 100232 752232 0 0 147388 0 2027 1048 3 5 92 0 0
1 0 67344 248428 100232 1313856 0 0 561280 0 5914 1021 9 16 75 0 0
1 0 67344 30984 100212 1531248 0 0 551424 0 5958 1238 10 16 73 1 0
1 0 67344 40308 100212 1522448 0 0 521344 0 6533 1699 9 19 72 0 0
0 0 67344 38160 100212 1526716 0 0 266652 0 3689 1512 5 10 85 1 0
0 0 67344 38224 100212 1526708 0 0 0 0 558 969 0 1 99 0 0
0 0 67344 37972 100220 1526700 0 0 0 12 506 888 1 1 99 0 0
0 0 67344 38256 100220 1526684 0 0 0 0 808 1485 0 0 100 0 0
0 0 67344 38224 100220 1526684 0 0 0 0 557 897 0 1 99 0 0
1 0 67344 38224 100220 1526628 0 0 0 0 492 811 0 1 99 0 0
跟上面1.3中的文件写出差不多,cache一直在增长,就是io中此时是bi在增长(因为是读取,刚才1.3示例中时输出)。
1.5 cache总结结合上面的示例,我们可以总结出来,cache可以用作从文件读取数据的页缓存,也可以用作写文件的页缓存。
结合man free命令来看下官方解释
root@7bc18553126f:/# man free
SYNOPSIS
free [options]
DESCRIPTION
cache Memory used by the page cache and slabs (Cached and SReclaimable in /proc/meminfo)
再通过man proc命令来看下
root@7bc18553126f:/# man proc
Cached %lu
In-memory cache for files read from the disk (the page cache). Doesn't include SwapCached.
总结:free命令中的Cache项 本质上就是对读写磁盘文件的内存缓存
2.Buffer需要首先说明一点,我在Mac机器上,用的Ubuntu docker机器,使用df -h命令查找出来的磁盘信息根本没法用,直接就报错了
root@7bc18553126f:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 59G 14G 42G 26% /
tmpfs 64M 0 64M 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/vda1 59G 14G 42G 26% /etc/hosts
tmpfs 995M 0 995M 0% /sys/firmware
直接对/dev/vda1进行操作,报错,不知道为啥。
所以,后来还是用的阿里云环境进行的操作。
2.1 dd命令测试磁盘块读取目前这台阿里云机器的df信息如下
[root@iZ8lgm9icspkthZ ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs 1.8G 740K 1.8G 1% /run
tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/vda1 40G 6.2G 34G 16% /
overlay 40G 6.2G 34G 16% /var/lib/docker/overlay2/d0411aece9995c0576bd787e4c44f47dddb0df68de4c3c6b9775513c9e3dc647/merged
overlay 40G 6.2G 34G 16% /var/lib/docker/overlay2/e882d72bc09cb2fff7b7716d19ccd74c9e44d3368ebd45fdb913df59ec4f8cfc/merged
tmpfs 363M 0 363M 0% /run/user/0
overlay 40G 6.2G 34G 16% /var/lib/docker/overlay2/dc7c2a0270aa9b0855f5c706ab96c1b6b2f704cd9a67e3d7d2452dc3863c0a14/merged
下面我们使用/dev/vda1来模拟测试
使用dd命令模拟磁盘块的读取
# 从/dev/vda1中读取数据,数据量为1024M
[root@iZ8lgm9icspkthZ ~]# dd if=/dev/vda1 of=/dev/null bs=1M count=1024
记录了1024+0 的读入
记录了1024+0 的写出
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 9.7295 s, 110 MB/s
2.2 vmstat命令监控内存信息
[root@iZ8lgm9icspkthZ ~]# vmstat -w 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 2768876 0 399400 0 0 0 10 2 1 19 9 73 0 0
1 0 0 2768736 0 399416 0 0 8 0 1854 3582 1 1 99 0 0
0 0 0 2768708 0 399416 0 0 16 0 1732 3397 0 1 99 0 0
0 1 0 2728596 38912 399576 0 0 39012 0 2202 3545 1 2 87 10 0
0 1 0 2617592 149504 399960 0 0 110592 2 2119 3580 0 3 57 40 0
0 1 0 2510576 256000 400460 0 0 106496 0 2270 3634 1 2 57 40 0
0 1 0 2399608 366592 400840 0 0 110596 0 2380 3559 0 2 59 39 0
0 1 0 2292192 473088 401468 0 0 106536 0 2982 4497 1 4 54 42 0
0 2 0 2181784 583680 401660 0 0 110804 0 3150 4582 1 3 17 80 0
0 1 0 2074788 690176 401924 0 0 106624 0 2285 4141 1 3 42 55 0
0 1 0 1968024 796672 402280 0 0 106496 0 1835 3381 1 3 49 48 0
0 1 0 1857300 907264 402568 0 0 110592 0 1971 3556 1 3 53 44 0
0 1 0 1750552 1013760 402784 0 0 106496 0 1802 3394 0 2 49 49 0
0 0 0 1710376 1054720 402928 0 0 41144 4 1890 3587 1 1 80 19 0
0 0 0 1710416 1054720 403044 0 0 0 0 1763 3443 0 1 99 0 0
1 0 0 1710416 1054720 403048 0 0 32 0 1895 3640 1 1 99 0 0
0 0 0 1710416 1054720 403048 0 0 0 0 1757 3434 0 1 99 0 0
既然是读取文件,那么如上所示:io列中的bi在快速变化,说明正在读取
此时Cache基本没有变化,而buff一直在增加。
2.3 buff总结结合上面的示例,我们可以总结出:buff是对磁盘数据的缓存。
结合man free命令来看下官方解释
root@7bc18553126f:/# man free
buffers
Memory used by kernel buffers (Buffers in /proc/meminfo)
再结合man proc命令看下
root@7bc18553126f:/# man proc
/proc/meminfo
Buffers %lu
Relatively temporary storage for raw disk blocks that shouldn't get tremendously large (20MB or so).
buffer是对原始磁盘块的临时存储,用来缓存磁盘数据,通常不会特别大(20M左右)。这样内核可以把分散的写集中起来,统一优化磁盘的写入。
总结:再来总结下buff和cache的不同:
buff:
buff是对原始磁盘块的临时存储,用来缓存磁盘数据,通常不会特别大(20M左右)。这样内核可以把分散的读写集中起来,统一优化磁盘的读取/写入。
cache:
cache是从磁盘读取文件的页缓存,缓存从文件读取的数据,这样,下次访问这些数据时,可以直接从内存中快速获取。
借用网络上的一张图,可以很清晰的展示两个的位置不同:
cache和buff都可以是读写的缓存,唯一的不同就是:buffer以裸设备、分区为背景;cache以文件系统中的文件为背景
参考:极客时间
【Linux学习】Linux free 命令学习_字节卷动的博客-CSDN博客_free命令