• Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决(续)


    作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息

    网址: http://www.cnblogs.com/panfeng412/archive/2013/12/17/drop-caches-under-linux-system-2.html

    前一篇文章里已经描述了具体遇到的问题及一些解决方法。但是还有些疑问点没有搞清楚,进一步学习了Linux系统下内存的分配使用机制,这里有两个资料讲的比较全面:

    Where is the memory going? Memory waste under Linux

    Where is the memory going?Memory usage in the 2.6 kernel

    以下记录的是进一步排查的进展情况。

    更深层次的原因

    前一篇文章里排查到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 <pid> -e trace=stat

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

    sudo strace -fp <pid> -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阈值之间,停止回收。

  • 相关阅读:
    括号匹配的检验
    学习过程中遇到的比较有价值的博客--整理
    Spring+SpringMVC+MyBatis的pom.xml依赖
    Hibernate内容详解
    Struts2的拦截器配置
    Maven构建Struts2项目
    Mybatis增删改查,Demo整合
    简单Java类 全网最详细讲解 !!!
    Javaoop 遇到的问题
    Bootstrap 前端框架 遇到的问题 解决方案
  • 原文地址:https://www.cnblogs.com/panfeng412/p/drop-caches-under-linux-system-2.html
Copyright © 2020-2023  润新知