free命令详解

free命令显示了系统中已使用和空闲的物理内存和交换内存,以及内核使用的buffer和cache的大小。命令中的数据是通过解析/proc/meminfo文件获得的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
[root@localhost ~]# free -w
total used free shared buffers cache available
Mem: 1014972 604816 65888 6880 164 344104 220752
Swap: 1048572 264 1048308
[root@localhost ~]# free -k
total used free shared buff/cache available
Mem: 1014972 605732 64932 6880 344308 219800
Swap: 1048572 264 1048308
[root@localhost ~]# cat /proc/meminfo
MemTotal: 1014972 kB
MemFree: 64916 kB
MemAvailable: 219784 kB
Buffers: 164 kB
Cached: 264984 kB
SwapCached: 8 kB
Active: 645456 kB
Inactive: 155036 kB
Active(anon): 509284 kB
Inactive(anon): 32940 kB
Active(file): 136172 kB
Inactive(file): 122096 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 1048572 kB
SwapFree: 1048308 kB
Dirty: 16 kB
Writeback: 0 kB
AnonPages: 535368 kB
Mapped: 44520 kB
Shmem: 6880 kB
Slab: 79160 kB
SReclaimable: 48748 kB
SUnreclaim: 30412 kB
KernelStack: 2704 kB
PageTables: 6608 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 1556056 kB
Committed_AS: 778052 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 27092 kB
VmallocChunk: 34359707152 kB
HardwareCorrupted: 0 kB
AnonHugePages: 356352 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 63424 kB
DirectMap2M: 985088 kB
[root@localhost ~]#

列内容说明:

  • total: 系统中的内存总量,对应/proc/meminfo中的MemTotal和SwapTotal的内容
  • used: 已占用内存大小,通过total - free - buffers - cache计算得出
  • free: 空闲内存大小,对应/proc/meminfo中的MemFree和SwapFree的内容
  • shared: 共享内存占用大小,通过情况都是tmpfs占用,对应/proc/meminfo中的Shmem的内容,在2.6.32内核中开始提供该内容显示,在不支持的系统中显示为0
  • buffers: 内核buffers占用大小,对应/proc/meminfo中的Buffers内容
  • cache: page cache和slabs占用的大小,对应/proc/meminfo中的Cached和Slab内容之和
  • buff/cache: buffers和cache之和
  • available: 在不考虑交换内存的情况下,估算有多少内存可以用来启动新应用。不同于cache和free字段提供的数据,该字段考虑了page cache,同时并非所有的可回收的slabs内存由于在使用中并不一定能被回收,对应/proc/meminfo中的MemAvailable内容(在内核3.14上可用,在内核2.6.27+上模拟,否则与free内容相同)

buffers与cache

linux缓存机制

在系统运行过程中,内核会利用空闲的物理内存,划出一部分区域作为buffers/cache,将一些程序使用过的硬盘数据读入缓存区域的内存,利用高速的内存读写特性提升数据的访问效率。

针对应用程序来说,通常情况下buffers/cache占用的内存是可用的,当应用程序需要用到内存的时候,会回收buffers/cache内存。

buffers与cache的区别

cache 指 page cache,它是针对文件系统的,是文件的缓存。当缓存中的文件被修改(写操作)后,linux不会立即执行写磁盘操作,而是把page cache中的页面标记为脏页,定期同步到存储设备中。

buffers 指 buffer cache,是磁盘块的缓存,是针对块设备的。直接对块设备的进行操作的数据会缓存到buffers中,例如,文件系统的元数据信息。

手动释放buffers和cache

/proc/sys/vm文档

1
2
3
4
5
6
#释放page cache
echo 1 > /proc/sys/vm/drop_caches
#释放可回收的slab对象(包括dentries和iinodes)
echo 2 > /proc/sys/vm/drop_caches
#释放page cache 和 slab 对象
echo 3 > /proc/sys/vm/drop_caches

通过写drop_caches文件是一个非破坏性(non-destructive)的操作,不会释放脏数据。在执行该命令前执行sync命令可以强制将一些脏数据刷盘,然后尽可能多的释放内存。

这个文件的内容并不能控制内核是否使用缓存机制。

是否需要手动清除缓存

通常情况下,应用程序在系统上稳定运行之后,free的值也会保持在一个稳定的值,虽然看上去比较小,Linux内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。一般情况下,这个操作中主要的内存释放都来自于对buffer/cache的释放。尤其是被使用更多的cache空间。既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放cache,作为free空间分给相关进程使用。所以一般情况下,我们认为buffer/cache空间可以被释放,这个理解是正确的。

通常情况下,当发生内存不足,应用程序获取不到内存,OOM等错误时,需要排查应用程序是否存在内存泄露的情况。针对内存泄露/内存溢出等导致内存不足的情况,可以通过swap的使用情况来快速判断(free中swap的使用情况,vmstate中si/so的值等)。

但是并非所有的buffer/cache都能释放

如何控制linux清理cache机制–内存整理影响系统性能案例

linux内存分配与回收

Linux中Buffer/Cache清理
Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决
Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决-2

禁用buffer/cache功能

可以在/etc/sysctl.conf中添加下面内容禁用buffer/cache功能

1
2
3
4
5
6
7
8
9
10
vm.dirty_ratio = 1
vm.dirty_background_ratio=1
vm.dirty_writeback_centisecs=2
vm.dirty_expire_centisecs=3
vm.drop_caches=3
vm.swappiness =100
vm.vfs_cache_pressure=163
vm.overcommit_memory=2
vm.lowmem_reserve_ratio=32 32 8
kern.maxvnodes=3

/proc/sys/vm/dirty_ratio

这个参数表示文件系统的写缓冲区占用系统内存的百分比,即当写缓冲使用到系统内存多少的时候,开始向磁盘写数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值。

/proc/sys/vm/dirty_background_ratio

这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比,表示系统内存的百分比,意思是当写缓冲使用到系统内存多少的时候,pdflush开始向磁盘写数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时, 应该降低其数值

/proc/sys/vm/dirty_writeback_centisecs

这个参数控制内核的脏数据刷新进程pdflush的运行间隔。单位是 1/100 秒。缺省数值是500,也就是 5 秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操

/proc/sys/vm/dirty_expire_centisecs

这个参数声明Linux内核写缓冲区里面的数据多“旧”了之后,pdflush进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。建议设置为 1500,也就是15秒算旧。

/proc/sys/vm/drop_caches

释放已经使用的cache

/proc/sys/vm/page-cluster

该文件表示在写一次到swap区的时候写入的页面数量,0表示1页,1表示2页,2表示4页。

/proc/sys/vm/swapiness

该文件表示系统进行交换行为的程度,数值(0-100)越高,越可能发生磁盘交换。

/proc/sys/vm/vfs_cache_pressure

该文件表示内核回收用于directory和inode cache内存的倾向