今天发现有一台线上的服务器内存报警,最近报警发现有好几次了,慎是恼火,想一探究竟,看了一下是一台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是被什么应用占用了这么大的内存,等我排查完后再做详细的记录