|
|
在Linux系统中,内存使用过程会有cache一直占用。Linux内核会在内存将要耗尽的时候,触发内存回收的工作,以便释放出内存给急需内存的进程使用。$ B9 u8 m1 N. e1 r$ @
一般情况下,这个操作中主要的内存释放都来自于对buffer/cache的释放。尤其是被使用更多的cache空间。既然它主要用来做缓存,只是在内存够用的时候加快进程对文件的读写速度,那么在内存压力较大的情况下,当然有必要清空释放cache,作为free空间分给相关进程使用。
% A0 r. S5 V/ l5 V2 r* Z& r" K所以一般情况下,我们认为buffer/cache空间可以被释放,这个理解是正确的。4 ?# Z. ~( o0 b3 ] `
但是这种清缓存的工作也并不是没有成本。理解cache是干什么的就可以明白清缓存必须保证cache中的数据跟对应文件中的数据一致,才能对cache进行释放。
6 ?. M5 _' w8 w9 [0 Y4 |8 z所以伴随着cache清除的行为的,一般都是系统IO飙高。因为内核要对比cache中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收。9 o4 q% {0 ]" f+ k( v3 k- B+ y
在系统中除了内存将被耗尽的时候可以清缓存以外,我们还可以使用下面这个文件来人工触发缓存清除的操作:; }6 {: o. J) j* e1 {
1
$ r7 m" O; Z4 B# L- P9 ^4 y2/ L7 V @" O" }* p) L6 C$ m
cat /proc/sys/vm/drop_caches
" b3 e* Q6 e9 X1 P) |# T- e& @) s0
4 g5 b) P9 U2 C) E, i5 L8 A0为默认值,即表示不释放! ^5 Y$ Z: \+ F ]" U6 O
echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。
( C" Y8 S1 ]; C& i. S& e gecho 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
5 Y& X, l2 F/ R* C3 {8 Xecho 3 > /proc/sys/vm/drop_caches:表示清除page cache和slab分配器中的缓存对象。
; f- f9 a" w! j# @; O4 a xCentOS系统手动释放内存# n: f4 d7 ~! v
线上集群后端某台Web服务器,我们观察到+buffers/cache值(即Linux内存的实际使用情况)一直都是5365左右,就算停掉Nginx+FastCGI程序也是一样,考虑到这台机器经常在使用rsync+inotify,肯定会存在着频繁存取文件。而Linux系统有一个特性:在Linux下频繁存取文件时,就会占用物理内存。当程序结束时并不会自动释放被占用的内存,而是一直作为Cache存在。实际上内核结束一个程序后,它是会释放内存的,但是内核并没有立刻将这部分收集到free当中,而是存在在cached或者buffer当中,提高系统的io效率,cache和buffered的内存是由内核进行动态的配置管理,如果系统的free大小不够的时候,系统会自动释放cache buffer的内存给程序使用(因此如果是看到used很多,来手动释放内存其实是不需要的)。& X+ O `1 d5 [( y+ P. X
8 N. W# D9 X O
操作步骤:; |0 [ I) K8 M" s5 G5 z
1、查询当前内存使用情况和释放缓存的参数
1 ~$ S8 i3 O! t( J% `; b1 ~8 Ffree -m; e: M' o% ~8 d+ ^ F) s
命令结果如示所示:
% L+ M( B- o* R" U( ] a- u3 t- E( X
total used free shared buffers cached
; R* G5 ^# E% e) iMem: 10988 6792 4196 0 168 10016 q0 t( e/ v0 i: o
-/+ buffers/cache: 5622 5365$ I! \. N, L% X+ N" @
Swap: 4295 0 4295. u) N# s; M- G- @; ]! F5 _5 R* @
查看释放缓存参数的命令,如下所示:9 A1 s& R% i V$ b9 U5 S
7 P/ n& ~" Y' n) {' }: Zcat /proc/sys/vm/drop_caches
3 m; A( } ^% k0 F# @$ F" p" C7 S+ u& x$ u
0为默认值,即表示不释放。
; O6 M" V( P. m! d$ ^6 [! H* L/ g2 u9 ^- ]1 ?6 K" L! s" z
2、使用sync命令,将系统缓存区中的脏数据写入磁盘中,包括已修改的i-node、已延迟的块I/O和读写映射文件,命令如下:
- T8 r; v6 l8 E5 G. C2 b- |4 J3 Y8 n4 V- T" b$ q6 y
sync* H5 P* P; u# g- N! j+ {
3、配置文件/proc/sys/vm/drop_caches中记录了缓存释放的参数,命令如下:4 J' \3 W& Z' |+ K+ W: _# |
5 d: ?" X* }. S$ A& ]
echo 3 > /proc/sys/vm/drop_caches
0 v/ ~/ l" ]0 [4、不重启机器使配置改生效,命令如下:$ w. R$ I8 ]# |9 G! c% P7 F
; S" x* ~; t0 d$ Q! T" |( m6 osysctl -p* D$ q5 P n3 L+ v% [
执行以上操作以后, + buffers/cache值由5365涨到了9000左右,这个值就恢复正常了,不过我觉得Linux管理内存的方式其实是很优异的,很多时候并不需要手动释放内存。' n8 S5 Z( K/ A; p1 g0 A) K& k
; J/ y! H* P: \' N! l1 y2 @, R
|
|