柴少鹏的官方网站 技术在分享中进步,水平在学习中升华

Linux 清除内存中的cache

首先以Centos6.4的来说,Centos7有些区别

一、buffer/cache/swap的介绍

#cat /etc/redhat-release  #查看系统版本

CentOS release 6.4 (Final)  

#free -m  #查看缓冲区及内存使用情况

                   total       used       free     shared    buffers     cached

Mem:          7814       7681        132          0         23       5727

-/+ buffers/cache:       1930       5884

Swap:         8191         32       8159


先看第二行Mem行:

Mem:          7814       7681        132          0         23       5727  #内存总大小为7814MB,使用7681MB,空闲132MB,共享内存0M,buffers:23MB,cached:5727MB

然后看地三行-/+ buffers/cache行:

-/+ buffers/cache:       1930       5884   #(-buffers/cache) used内存数:1930MB(指的第一部分Mem行中的used – buffers – cached),(+buffers/cache) free内存数:5884MB(指的第一部分Mem行中的free + buffers + cached),也就是说-buffers/cache反映的是被程序实实在在吃掉的内存,而+buffers/cache反映的是可以挪用的内存总数.

然后看第四列Swap行:

Swap:         8191         32       8159 #这也就是我们经常说的虚拟内存,8192为swap分区的总大小为8192MB,32为swap分区的使用为32MB,8159为swap空闲为8159MB。


swap分区的作用:

Linux内核为了提高读写效率与速度,会将文件在内存中进行缓存,这部分内存就是Cache Memory(缓存内存)。即使你的程序运行结束后,Cache Memory也不会自动释放。这就会导致你在Linux系统中程序频繁读写文件后,你会发现可用物理内存变少。当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。这样,系统总是在物理内存不够时,才进行Swap交换。所以swap分区不被占用或者占用很少,说明现在系统内存够用,运行还算良好,不会影响系统运行。


首先,当物理内存不足以支撑系统和应用程序(进程)的运作时,这个Swap交换分区可以用作临时存放使用率不高的内存分页,把腾出的内存交给急需的应用程序(进程)使用。有点类似机房的UPS系统,虽然正常情况下不需要使用,但是异常情况下, Swap交换分区还是会发挥其关键作用。

其次,即使你的服务器拥有足够多的物理内存,也有一些程序会在它们初始化时残留的极少再用到的内存分页内容转移到 swap 空间,以此让出物理内存空间。对于有发生内存泄漏几率的应用程序(进程),Swap交换分区更是重要,因为谁也不想看到由于物理内存不足导致系统崩溃。

最后,现在很多个人用户在使用Linux,有些甚至是PC的虚拟机上跑Linux系统,此时可能常用到休眠(Hibernate),这种情况下也是推荐划分Swap交换分区的。

其实少量使用Swap交换空间是不会影响性能,只有当RAM资源出现瓶颈或者内存泄露,进程异常时导致频繁、大量使用交换分区才会导致严重性能问题。另外使用Swap交换分区频繁,还会引起kswapd0进程(虚拟内存管理中, 负责换页的)耗用大量CPU资源,导致CPU飙升。



空闲内存/已用内存换算(也可参考-/+ buffers/cache这行信息也是内存正确使用率):

空闲内存=free(132)+buffers(23)+cached(5727)=5882

已用内存=total(7814)-空闲内存(5882)=1932


buffers和cache的区别:

为了提高磁盘存取效率, Linux做了一些精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了I/O系统调用(比如read,write,getdents)的时间。

磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。

Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,因为Buffer Cache就是缓存磁盘块的。但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。

Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。

Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。

缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux有一个守护进程定 期清空缓冲内容(即写如磁盘),也可以通过sync命令手动清空缓冲。

简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。

所以我们看linux,只要不用swap的交换空间,就不用担心自己的内存太少.如果常常swap用很多,可能你就要考虑加物理内存了.这也是linux看内存是否够用的标准.

Cache: 高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周 期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,这样就减少了CPU的等待时间,提 高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache。

如果 cache 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache住,那么磁盘的读IO bi会非常小。

缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。


注:下面是Centos7.2系统free -m的显示:

#free -m

              total        used        free      shared  buff/cache   available

Mem:          64252        2924         258        3233       61069       57654

Swap:          8191         144        8047


博文来自:www.51niux.com

二、内存查看命令

2.1 用free加各种参数例如:

命令参数:

-b  以Byte为单位显示内存使用情况。 

-k  以KB为单位显示内存使用情况。 

-m  以MB为单位显示内存使用情况。

-g   以GB为单位显示内存使用情况。 

-o  不显示缓冲区调节列。 

-s<间隔秒数>  持续观察内存使用状况。 

-t  显示内存总和列。 

-V  显示版本信息。

# free -k -s 1 #显示单位为KB,然后每一秒刷新一次。

但是这也只能显示一个总量,如果内存真的是被使用了,我们应该如何查询哪些进程占用内存过大呢?

2.2 top命令

执行top,然后按shift+M,可以对进行使用内存情况从大到小排序

blob.png


2.3 ps命令

# ps -aux|sort -k 4 -n  #为了查看方便,让其从小到大排序

blob.png

第一列:USER  用户名

第二列:PID 进程ID

第三列:%CPU 进程的cpu占用率

第四列:%MEM 进程的内存占用率

第五列:VSZ 虚拟内存中进程的大小,单位KB

第六列:RSS 进程实际内存大小,单位KB

第七列:TTY 与进程关联的终端(tty)

第八列:STAT 进程的状态

下面为STAT的状态码:

R 运行    Runnable (on run queue)            正在运行或在运行队列中等待。
S 睡眠    Sleeping                休眠中, 受阻, 在等待某个条件的形成或接受到信号。
I 空闲    Idle
Z 僵死    Zombie(a defunct process)        进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放。
D 不可中断    Uninterruptible sleep (ususally IO)    收到信号不唤醒和不可运行, 进程必须等待直到有中断发生。
T 终止    Terminate                进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行。
P 等待交换页
W 无驻留页    has no resident pages        没有足够的记忆体分页可分配。
X 死掉的进程
< 高优先级进程                    高优先序的进程
N 低优先    级进程                    低优先序的进程
L 内存锁页    Lock                有记忆体分页分配并缩在记忆体内
s 进程的领导者(在它之下有子进程);
l 多进程的(使用 CLONE_THREAD, 类似 NPTL pthreads)
+ 位于后台的进程组

第九列:START  进程启动时间和日期

第十列:TIME  进程使用的总cpu时间

第十一列: COMMAND 正在执行的命令行命令

注:如果要进一步排查内存占用问题,可以用# pstree PID -ap #树状图的显示进程间的关系,默认PID为1,也就是全部

# ps -eo user,pid,command|grep mysql  #查出mysql的uid

# pstree 3584 -ap  #查看mysql下面都有哪些进程

blob.png

注:pgrep

pgrep命令以名称为依据从运行进程队列中查找进程,并显示查找到的进程id。每一个进程ID以一个十进制数表示,通过一个分割字符串和下一个ID分开,默认的分割字符串是一个新行。对于每个属性选项,用户可以在命令行上指定一个以逗号分割的可能值的集合

参数: -o:仅显示找到的最小(起始)进程号; -n:仅显示找到的最大(结束)进程号; -l:显示进程名称; -P:指定父进程号; -g:指定进程组; -t:指定开启进程的终端; -u:指定进程的有效用户ID。

# pgrep -l mysqld  

3584 mysqld_safe

3752 mysqld


博文来自:www.51niux.com

2.4  #cat /proc/meminfo  #又或者说,我发现系统占用内存不大,内存都被缓存起来了,想看看内存使用的详细信息。

#cat /proc/meminfo

MemTotal:        8002048 kB   #所有可用RAM大小(即物理内存减去一些预留位和内核的二进制代码大小)

MemFree:          141316 kB   #LowFree和HighFree的综合,被系统留着未使用的内存

Buffers:            3492 kB    #用来给文件做缓冲大小

Cached:          5850688 kB   #被高速缓冲存储器(cache memory)用的内存的大小

SwapCached:         1004 kB  #被高速缓冲存储器(cache memory)用的交换空间的大小

Active:          3685356 kB  #在活跃使用中的缓冲或高速缓冲存储器页面文件的大小,除非非常必要否则不会被移作他用.

Inactive:        3634468 kB  # 在不经常使用中的缓冲或高速缓冲存储器页面文件的大小,可能被用于其他途径.

Active(anon):     760408 kB  

Inactive(anon):   706016 kB

Active(file):    2924948 kB

Inactive(file):  2928452 kB

Unevictable:           0 kB

Mlocked:               0 kB

SwapTotal:       8388600 kB   #交换空间的总大小

SwapFree:        8355464 kB   #未被使用交换空间的大小

Dirty:             60612 kB   #等待被写回到磁盘的内存大小

Writeback:            44 kB  #正在被写回到磁盘的内存大小

AnonPages:       1465384 kB  #未映射页的内存大小

Mapped:            10028 kB  #设备和文件等映射的大小

Shmem:               128 kB  

Slab:             393984 kB   #内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗。

SReclaimable:     314272 kB  #可收回Slab的大小

SUnreclaim:        79712 kB   #不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)

KernelStack:        6656 kB

PageTables:        13848 kB  #管理内存分页页面的索引表的大小。

NFS_Unstable:          0 kB   #不稳定页表的大小

Bounce:                0 kB

WritebackTmp:          0 kB

CommitLimit:    12389624 kB

Committed_AS:    6404932 kB

VmallocTotal:   34359738367 kB   #可以vmalloc虚拟内存大小

VmallocUsed:      291660 kB  #已经被使用的虚拟内存大小

VmallocChunk:   34359426484 kB  

HardwareCorrupted:     0 kB

AnonHugePages:    243712 kB

HugePages_Total:       0    #内存大页的总数

HugePages_Free:        0    #内存大页剩余数量

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB  #内存大页的大小(64位操作系统中有2MB/1GB两种,默认是2MB。)

DirectMap4k:        4096 kB

DirectMap2M:     2084864 kB

DirectMap1G:     6291456 kB


博文来自:www.51niux.com

三、手工释放内存区缓存(这是只是记录,但是不建议操作,本来cache就是为了提升系统性能,是linux区别于windows的优势所在,缓解磁盘的压力,如果真有必要可手工释放一下,也不要永久的的让cache作用无法发挥)

# sync; echo 1 > /proc/sys/vm/drop_caches  #释放 pagecache

# sync; echo 2 > /proc/sys/vm/drop_caches    #释放  dentries 和 inodes:

# sync; echo 3 > /proc/sys/vm/drop_caches  #释放 pagecache,dentries 和 inodes:

# sync; echo 0 > /proc/sys/vm/drop_caches  #默认0为不释放,让系统自己调节

注:

操作前要使用sync,强制将内存中内容写入硬盘,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。这一步是确保第二步的安全性。防止数据或操作丢失。

linux内核2.6和内核3系列的区别:

内核2.6的版本执行上述的操作都没问题的,但是到了内核3系列,就不能执行echo 0 >/proc/sys/vm/drop_caches的操作了,这是一个坑,重启才能改回去

# echo 0 >/proc/sys/vm/drop_caches

-bash: echo: write error: Invalid argument

# sysctl -a|grep vm.drop_caches  #内核中有这个参数

vm.drop_caches = 3

# sysctl -w vm.drop_caches=0  #也写不进去,这个在内核2.6系列上面可以的,这也是手工释放内存缓存的另一种形式(sysctl -w vm.drop_caches=3)

error: "Invalid argument" setting key "vm.drop_caches"

# sysctl -w vm.drop_caches=1  #执行其他的是没问题的,但是就是执行0的插入不可以,要重启服务器。

vm.drop_caches = 1


注:

swap清理:
swapoff -a && swapon -a
注意:这样清理有个前提条件,空闲的内存必须比已经使用的swap空间大。


上述只是暂时生效,但是系统重启后,系统还是按照自己默认的方法去使用缓存,有的网友会写定时任务脚本晚上去释放一下内存cache,还有一种暴力的永久生效的方法,使cache的作用基本无法发挥。

修改/etc/sysctl.conf 添加如下选项后就不会内存持续增加(这些配置摘抄自网上,未做测试,只是记录一下)
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

这个参数控制文件系统的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,表示当写缓冲使用到系统内存多少的时候,开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般启动上缺省是 10。设1加速程序速度

/proc/sys/vm/dirty_background_ratio

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

/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

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

作者:忙碌的柴少 分类:解决小问题 浏览:11743 评论:0
留言列表
发表评论
来宾的头像