今天发现有一台线上的服务器内存报警,最近报警发现有好几次了,慎是恼火,想一探究竟,看了一下是一台16G内存的服务器,free 了一下看了一下确实是没有多少内存可用了,再看了一下都跑了一些什么应用,结果发现只跑了一个数据库跟一个跨服,当时心里就感觉16G内存不可能用完,
[[email protected] 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分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。
查看了一下内存信息如下:
[[email protected] 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内存的大小,看看是不是吻合 [[email protected] dingmh]#echo `cat /proc/slabinfo |awk ‘BEGIN{sum=0;}{sum=sum+$3*$4;}END{print sum/1024/1024}‘` MB 4917.96 MB
slab可以回收的内存是可以通过触发来自动回收的
[[email protected] logs]#sysctl -a |grep free vm.min_free_kbytes = 67584 #意思是说只有在系统内存不满足这个值的时候才能触发,但是等到真的到这个值的时候,基本上看不到了 vm.extra_free_kbytes = 0 [[email protected] logs]#sysctl -w vm.min_free_kbytes=1048576 vm.min_free_kbytes = 1048576 设置成1G后,系统立马从slab上释放了5g内存
具体slab是被什么应用占用了这么大的内存,等我排查完后再做详细的记录
时间: 2024-10-21 19:40:31