首页 > 代码库 > 一次生产环境服务器内存不足的排查经过

一次生产环境服务器内存不足的排查经过

   今天发现有一台线上的服务器内存报警,最近报警发现有好几次了,慎是恼火,想一探究竟,看了一下是一台16G内存的服务器,free 了一下看了一下确实是没有多少内存可用了,再看了一下都跑了一些什么应用,结果发现只跑了一个数据库跟一个跨服,当时心里就感觉16G内存不可能用完,

[root@hqg-222-99. logs]#ps aux|awk ‘{sum=sum + $6};END {print sum/1024"M"}‘
4363.01M  
才使用了4g多一点

#也可以通过这段在网上找到的脚本查看
#/bin/bash                                                                                                               
for PROC in `ls  /proc/|grep "^[0-9]"`
do
  if [ -f /proc/$PROC/statm ]; then
      TEP=`cat /proc/$PROC/statm | awk ‘{print ($2)}‘`
      RSS=`expr $RSS + $TEP`
  fi
done
RSS=`expr $RSS \* 4`
echo $RSS"KB"

再看看cache也没有占用多少,那内存去哪了呢?

下载nmon 进行内存查看:


wget ## http://sourceforge.net/projects/nmon/files/nmon_linux_14i.tar.gz 
直接./nmon  
按m显示内存的使用情况
这个是我释放了后的截图

技术分享

当时看着free只有几百M了,slab 占用了10G slab是什么呢,经过查询资料后的解释是

slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内存碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。

查看了一下内存信息如下:

[root@hqg-222-99. logs]#cat /proc/meminfo 
MemTotal:       16100652 kB
MemFree:          254236 kB
Buffers:          169600 kB
Cached:           186728 kB
SwapCached:        10064 kB
Active:          3806092 kB
Inactive:        1064960 kB
Active(anon):    3566956 kB
Inactive(anon):   948732 kB
Active(file):     239136 kB
Inactive(file):   116228 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:        511992 kB
SwapFree:         446100 kB
Dirty:                32 kB
Writeback:            72 kB
AnonPages:       4504536 kB
Mapped:            21212 kB
Shmem:               964 kB
Slab:           10621812 kB    #slab占用的内存大小10G
SReclaimable:   10590404 kB    #slab可回收的内存大小
SUnreclaim:        31408 kB    #slab不可回收的内存大小
KernelStack:        2680 kB
PageTables:        15184 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8562316 kB
Committed_AS:    7259324 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       65132 kB
VmallocChunk:   34359627272 kB
HardwareCorrupted:     0 kB
AnonHugePages:   4325376 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        8176 kB
DirectMap2M:    33546240 kB

#可以通过
slabtop  查看具体是什么占用了内存,

可以统计slab内存的大小,看看是不是吻合
[root@hqg-222-99. dingmh]#echo `cat /proc/slabinfo |awk ‘BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024/1024}‘` MB
4917.96 MB

slab可以回收的内存是可以通过触发来自动回收的

[root@hqg-222-99. logs]#sysctl  -a |grep free
vm.min_free_kbytes = 67584   #意思是说只有在系统内存不满足这个值的时候才能触发,但是等到真的到这个值的时候,基本上看不到了
vm.extra_free_kbytes = 0

[root@hqg-222-99. logs]#sysctl -w vm.min_free_kbytes=1048576  
vm.min_free_kbytes = 1048576
设置成1G后,系统立马从slab上释放了5g内存

具体slab是被什么应用占用了这么大的内存,等我排查完后再做详细的记录

本文出自 “脚下的痕迹” 博客,请务必保留此出处http://dingmh.blog.51cto.com/188555/1846883

一次生产环境服务器内存不足的排查经过