前言
Linux系统的缓存机制是相当先进的,他会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作。以下几类操作会很占内存:
- 频繁 或 大量的文件存取操作
- 程序测试频发崩溃
- 服务的大量访问和数据读写
某些操作会产生大量的缓存,当我们完成这些操作后,这部分缓存就要等待系统清除。
由于程序BUG 或 服务崩溃等问题,导致没有线程对象能使用它们,变成了垃圾缓存,但是系统不知道,迟迟不能清除这些缓存。
对于上述情况,我们都是通过手动的方式及时、彻底的释放缓存。
手动释放缓存
一、查看当前系统缓存情况
通过 free 命令,我们可以查看系统当前的各类内存使用情况,该命令详情在此不做说明。
[root@localhost /]# free -h
total used free shared buff/cache available
Mem: 15G 616M 14G 441M 901M 14G
Swap: 8.0G 0B 8.0G
二、drop_caches文件及其值说明
/proc 是一个虚拟文件系统,我们可以通过对它的读写操作做为与 kernel(系统内核)实体间进行通信的一种手段。也就是说可以通过修改 /proc 中的文件,来对当前 kernel 的行为做出调整。
因此,我们可以通过调整 /proc/sys/vm/drop_caches 的值来释放内存。该文件的值可以为 0~3 之间的任意数字,代表着不同的含义:
- 0:不释放(系统默认值)。默认情况下表示不释放内存,由操作系统自动管理。
- 1:释放页缓存(Page Cache)。
- 2:释放 dentries(目录缓存)和 inodes(节点缓存)。
- 3:释放所有缓存(Page Cache、dentries 和 inodes)。
三、将未写的缓存写入磁盘
需要说明的是,本篇文章介绍的手动清除缓存的方式,实际上就是通知系统内核马上清除缓存。
在手动释放缓存之前,我们还需要做一件非常重要的事情,那就是执行 sync 命令。该命令可以将缓存中的数据写入磁盘,避免缓存数据丢失。
sync 命令运行 sync 子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。
sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。
四、通知kernel清除缓存
只需要修改该 /proc/sys/vm/drop_caches 文件的值即可。注意,只能通过echo命令修改,无法通过vim命令修改。
[root@localhost /]# echo 3 > /proc/sys/vm/drop_caches ## 清除所有缓存
示例
## 查看系统当前的缓存情况
[root@localhost home]# free -h
total used free shared buff/cache available
Mem: 15G 591M 14G 441M 540M 14G
Swap: 8.0G 0B 8.0G
## 打包压缩/tmp目录
[root@localhost home]# tar -cvzf tmp.tar.gz /tmp
## 再次查看系统的缓存使用情况,可以看到在执行tar命令之后,缓存使用很高
[root@localhost home]# free -h
total used free shared buff/cache available
Mem: 15G 591M 13G 441M 1.2G 14G
Swap: 8.0G 0B 8.0G
## 将未写的缓存写入磁盘,避免数据丢失
[root@localhost home]# sync
## 通知kernel清除缓存
[root@localhost home]# echo 3 > /proc/sys/vm/drop_caches
## 再次查看系统的缓存使用情况,可以看到缓存被清除了一部分
[root@localhost home]# free -h
total used free shared buff/cache available
Mem: 15G 593M 14G 441M 542M 14G
Swap: 8.0G 0B 8.0G