linux 应用内存分析,分析Linux内存使用 - Goopand's OS Space - OSCHINA - 中文开源技术交流社区...

今天发现一台线上服务器内存使用率报警了,连上去后发现通过free命令查看到的内存用了很多,如图:

051d80a13f0e2ec37d0e22b34898d596.png

减去buffers和cached使用的部分,程序实际占用了5835M的内存,但是通过ps命令查看到的内存却只有2000多M,如图:

84ad6cbfd111c4217ab6a6360d4fab80.png

查看到的内存只有2172M(ps和top里的内存数据都是通过读取/proc/pid/statm文件的数据得来的),那剩余的3个多G的内存哪里去了?通过在网上搜索后找到了一篇很详细的文章,下文中大部分也是参考这篇文件测试的,完全符合文章作者的分析,引用原文的一段话:内核为了高性能每个需要重复使用的对象都会有个池,这个slab池会cache大量常用的对象,所以会消耗大量的内存。运行 slabtop 命令可以查看相关信息:

d773130a138d7199d83fece19a8b09c0.png

可以看到一个名字为dentry的对象占用了3585800/1024大约3502M的内存,看来剩余的内存大部分被这玩意儿吃掉了,网上查了下dentry对象是文件路径名与inode之间的映射,由于程序进行了大量的文件读写操作造成系统过多的缓存了dentry从而占用了大量的内存,最终确定可能是lucene一个全文索引工具引起的问题,解决方法还有待开发方面解决。

手动释放这些内存方法:

#执行前先执行下sync命令

#To free pagecache:

echo 1 > /proc/sys/vm/drop_caches

#To free dentries and inodes:

echo 2 > /proc/sys/vm/drop_caches

#To free pagecache, dentries and inodes:

echo 3 > /proc/sys/vm/drop_caches

总结一下:linux系统内存主要用于3个地方:1 进程 ,2 slab,3 pagetab。系统free 命令查看到是系统整体的内存使用情况,ps 和top 都是根据进程来显示的所以,并不会显示像slab和pagetab这些占用的内存信息。

以下内容转自http://ks0101.blog.51cto.com/8639108/1365770

更深层次的原因

上文排查到Linux系统中有大量的dentry_cache占用内存,为什么会有如此多的dentry_cache呢?

1. 首先,弄清楚dentry_cache的概念及作用:目录项高速缓存,是Linux为了提高目录项对象的处理效率而设计的;它记录了目录项到inode的映射关系。因此,当应用程序发起stat系统调用时,就会创建对应的dentry_cache项(更进一步,如果每次stat的文件都是不存在的文件,那么总是会有大量新的dentry_cache项被创建)。

2. 当前服务器是storm集群的节点,首先想到了storm相关的工作进程,strace一下storm的worker进程发现其中有非常频繁的stat系统调用发生,而且stat的文件总是新的文件名:

sudo strace -fp  -e trace=stat

3. 进一步观察到storm的worker进程会在本地目录下频繁的创建、打开、关闭、删除心跳文件,每秒钟一个新的文件名:

sudo strace -fp  -e trace=open,stat,close,unlink

以上就是系统中为何有如此多的dentry_cache的原因所在。

一个奇怪的现象

通过观察/proc/meminfo发现,slab内存分为两部分:

SReclaimable // 可回收的slab

SUnreclaim // 不可回收的slab

当时服务器的现状是:slab部分占用的内存,大部分显示的都是SReclaimable,也就是说可以被回收的。

但是通过slabtop观察到slab内存中最主要的部分(dentry_cache)的OBJS几乎都是ACTIVE的,显示100%处于被使用状态。

OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME

13926348 13926348 100%    0.21K 773686       18   3494744K dentry_cache

334040 262056  78%    0.09K   8351       40     33404K buffer_head

151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache

为什么显示可回收的,但是又处于ACTIVE状态呢?求Linux内核达人看到后热心解释下:(

会不会由于是ACTIVE状态,导致dcache没有被自动回收释放掉呢?

让系统自动回收dcache

上一小节,我们已经提到,服务器上大部分的slab内存是SReclaimable可回收状态的,那么,我们能不能交给操作系统让他在某个时机自动触发回收操作呢?答案是肯定的。

查了一些关于Linux dcache的相关资料,发现操作系统会在到了内存临界阈值后,触发kswapd内核进程工作才进行释放,这个阈值的计算方法如下:

1. 首先,grep low /proc/zoneinfo,得到如下结果:

low      1

low      380

low      12067

2. 将以上3列加起来,乘以4KB,就是这个阈值,通过这个方法计算后发现当前服务器的回收阈值只有48MB,因此很难看到这一现象,实际中可能等不到回收,操作系统就会hang住没响应了。

3. 可以通过以下方法调大这个阈值:将vm.extra_free_kbytes设置为vm.min_free_kbytes和一样大,则/proc/zoneinfo中对应的low阈值就会增大一倍,同时high阈值也会随之增长,以此类推。

$ sudo sysctl -a | grep free_kbytes

vm.min_free_kbytes = 39847

vm.extra_free_kbytes = 0

$ sudo sysctl -w vm.extra_free_kbytes=836787  ######1GB

4. 举个例子,当low阈值被设置为1GB的时候,当系统free的内存小于1GB时,观察到kswapd进程开始工作(进程状态从Sleeping变为Running),同时dcache开始被系统回收,直到系统free的内存介于low阈值和high阈值之间,停止回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值