今天要聊的是linux的free命令,它输出的是内存相关的信息。该命令看似简单,但它所涉及到的一些内存信息经常被误解,所以有必要澄清。
在开发和运维中,我们不仅需要关注CPU资源的消耗情况,还需要关注内存资源的消耗情况,这就必须涉及到free命令,本文将进行实战讲解。
我的云服务器内存简介
我买了一台老东家的云服务器,每年三四百块钱,基本参数如下:
可以看到,内存1G,即1024M. 当我用free命令查看时,结果如下:
ubuntu@VM-0-15-ubuntu:~$ free -wh
total used free shared buffers cache available
Mem: 864M 403M 79M 20M 60M 321M 253M
Swap: 0B 0B 0B
ubuntu@VM-0-15-ubuntu:~$
我买的内存明明是1G, 怎么total才864M呢?
原因是:服务器启动时,会初始化相关设备,会占用内存。而且在linux内核启动时,也会占用一部分内存。那个total 864M是指能被应用程序使用的内存。
如果要看最原始的内存,可用dmidecode命令,看到最大可能的内存是1G(所有内存插槽之和),我的云服务器实际只有1个内存条,这个内存条刚好是1024M.
所以,这台云服务器的总实际物理内存就是1024M:
ubuntu@VM-0-15-ubuntu:~$ sudo dmidecode -t memory
# dmidecode 3.0
Getting SMBIOS data from sysfs.
SMBIOS 2.4 present.
Handle 0x1000, DMI type 16, 15 bytes
Physical Memory Array
Location: Other
Use: System Memory
Error Correction Type: Multi-bit ECC
Maximum Capacity: 1 GB
Error Information Handle: Not Provided
Number Of Devices: 1
Handle 0x1100, DMI type 17, 21 bytes
Memory Device
Array Handle: 0x1000
Error Information Handle: 0x0F01
Total Width: 64 bits
Data Width: 64 bits
Size: 1024 MB
Form Factor: DIMM
Set: None
Locator: DIMM 0
Bank Locator: Not Specified
Type: RAM
Type Detail: None
ubuntu@VM-0-15-ubuntu:~$
新版linux的free命令
我注意到, 跟几年前相比,free命令展示的内容和含义有变化。直接来看新版linux的free命令介绍:
free displays the total amount of free and used physical and swap memory in the system, as well as the buffers
and caches used by the kernel. The information is gathered by parsing /proc/meminfo. The displayed columns are:
total Total installed memory (MemTotal and SwapTotal in /proc/meminfo)
used Used memory (calculated as total - free - buffers - cache)
free Unused memory (MemFree and SwapFree in /proc/meminfo)
shared Memory used (mostly) by tmpfs (Shmem in /proc/meminfo, available on kernels 2.6.32, displayed as zero if
not available)
buffers
Memory used by kernel buffers (Buffers in /proc/meminfo)
cache Memory used by the page cache and slabs (Cached and Slab in /proc/meminfo)
buff/cache
Sum of buffers and cache
available
Estimation of how much memory is available for starting new applications, without swapping. Unlike the
data provided by the cache or free fields, this field takes into account page cache and also that not
all reclaimable memory slabs will be reclaimed due to items being in use (MemAvailable in /proc/meminfo,
available on kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as free)
可见,free命令从/proc/meminfo获取内存相关信息。而且,有如下关系式:
buffers/cache的含义
那么,应用程序和linux操作系统会怎样看待buffers/cache呢?如下图:
在旧版linux中,free命令的结果把buffers/cache归纳到used中。可见,这是站在linux视角的(如下图片是另外一台服务器):
然而,在新版linux中,free命令的结果没有把buffers/cache归纳到used中。可见,这是站在应用程序角度的,如下:
ubuntu@VM-0-15-ubuntu:~$ free -wh
total used free shared buffers cache available
Mem: 864M 403M 79M 20M 60M 321M 253M
Swap: 0B 0B 0B
ubuntu@VM-0-15-ubuntu:~$
所以,在新版linux free命令的结果中,有如下关系式:
total = used + free + buffers + cache
站在应用程序的角度,可用内存为:free加buffers/cache之和。然而,实际上只有部分buffers/cache能被应用程序使用,所以一般会有:
available < free + buffers + cache
顺便说一下,在后续的叙述中,我们都是针对新版linux的free命令。
内存消耗的程序验证
我们用程序来验证一下内存的消耗过程(不考虑虚拟内存):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
int mb = 0;
char* buffer;
while((buffer=malloc(1024 * 1024 * 10)) != NULL)
{
memset(buffer, 0, 1024 * 1024 * 10);
mb += 10;
printf("Allocated %d MB\n", mb);
sleep(1);
}
return 0;
}
运行程序,可以看到free被不断消耗, available也随之变化:
free的值被消耗完毕后,buffers和cache开始出场了,承担起了被消耗的重任。但是,要注意,并不是所有的buffers和cache都能被消耗殆尽的。
所以,最后进程出现OOM(Out Of Memory)时,cache还有几十M, 而available几乎没有了,如下图所示:
我们看到进程被kill了:
dmesg OOM信息如下:
虚拟内存消耗的程序验证
linux真的这么弱吗?申请290M内存后就扛不住了?简直笑话。
来看free命令结果的Swap信息,可以看到,都是0:
ubuntu@VM-0-15-ubuntu:~$ free -wh
total used free shared buffers cache available
Mem: 864M 449M 234M 20M 8.1M 171M 238M
Swap: 0B 0B 0B
也就是说,没有开启linux系统的虚拟内存。好的,那我们来开启2G的虚拟内存,如下:
ubuntu@VM-0-15-ubuntu:~$ free -wm
total used free shared buffers cache available
Mem: 864 439 240 20 10 174 246
Swap: 2047 0 2047
然后,我们来运行程序,并观察内存消耗。可以看到,最开始消耗的是available内存:
当available内存消耗到一定程度后,才开始使用虚拟内存:
当虚拟内存使用完毕后,实在没办法,又开始去消耗available内存,而当available内存被耗尽后,进程被OOM机制给kill了,然后各内存被释放出来:
可以看到,进程申请了2G多的内存后才被kill:
dmesg OOM信息如下:
结合上述实验,我们可以得知:
-
free接近0时,别紧张。
-
available接近0时,有问题。
-
OOM时,有问题。
生产环境的线上的服务器,有的开启了虚拟内存,有的没有开启虚拟内存。
我刚看了一台线上服务器,没有开启虚拟内存,其内存插槽共144个,每个32G, 故总共支持4608G的内存。
该服务器实际插了4个内存条,故总实际物理内存是128G,除系统占用的内存外,留给应用程序的总内存是125G,available内存是109G, 这内存真是够多的啊:
taoge:~$ sudo dmidecode -t memory | grep GB
Maximum Capacity: 4608 GB
Size: 32 GB
Size: 32 GB
Size: 32 GB
Size: 32 GB
taoge:~$ free -wh
total used free shared buffers cache available
Mem: 125G 20G 7.0G 1.3G 369M 97G 109G
Swap: 0B 0B 0B
到此为止,我们对linux free命令和各种内存有了更清晰的认识,下次就不会再犯迷糊了。