谁偷了我的内存?记一次内存占用过高的排查

2018-08-21:
内存升到44G了,看不下去了,决定手动清理

sync
echo 2 > /proc/sys/vm/drop_caches

又看了很多文章,每打开一个文件就会增加 dentry 这个程序有大量的Curl请求以及多进程的任务组。这个应该就是问题了吧。

项目服务器是 8H64G 的 EC2,因为项目数据量很大,监控程序一直显示真实内存占用在 47G 左右,本以为是Mysql占用过大导致的。htop图显示如下:

htop1

图中显示 Mysql 内存占用 2.1%,但是出现了很多列,肤浅的我错误的认为这些都是 Mysql,以 n*2.1 来计算 Mysql 的占用,经过V2er们的指点,得知了在 htop 中默认是以线程展示数据的,Mysql是多线程程序,多个线程之间的内存是共享的,通过 H 指令切换到非线程模式。

htop2

内存占用最高的还是 Mysql 不过他的内存占用也只有 2.4%。但是内存使用显示已经用了 48G 的内存。
首先有人提到了 tmpfs ,系统分配了 31G 的 tmpfs,本以为确实是这里占用掉了内存,但是查完资料发现 tmpfs 不使用的话是不会占用内存的,有人让我贴出了 cat /proc/meminfo

cat /proc/meminfo 
MemTotal: 62919396 kB 
MemFree: 2228000 kB 
MemAvailable: 60639408 kB 
Buffers: 327824 kB 
Cached: 10384060 kB 
SwapCached: 0 kB 
Active: 8945140 kB 
Inactive: 3568212 kB 
Active(anon): 1801992 kB 
Inactive(anon): 9432 kB 
Active(file): 7143148 kB 
Inactive(file): 3558780 kB 
Unevictable: 0 kB 
Mlocked: 0 kB 
SwapTotal: 0 kB 
SwapFree: 0 kB 
Dirty: 76 kB 
Writeback: 0 kB 
AnonPages: 1801496 kB 
Mapped: 52352 kB 
Shmem: 9940 kB 
Slab: 48031092 kB 
SReclaimable: 47962884 kB 
SUnreclaim: 68208 kB 
KernelStack: 3376 kB 
PageTables: 14700 kB 
NFS_Unstable: 0 kB 
Bounce: 0 kB 
WritebackTmp: 0 kB 
CommitLimit: 31459696 kB 
Committed_AS: 3442324 kB 
VmallocTotal: 34359738367 kB 
VmallocUsed: 0 kB 
VmallocChunk: 0 kB 
AnonHugePages: 26624 kB 
HugePages_Total: 0 
HugePages_Free: 0 
HugePages_Rsvd: 0 
HugePages_Surp: 0 
Hugepagesize: 2048 kB 
DirectMap4k: 12288 kB 
DirectMap2M: 63987712 kB 

这位朋友提出了 “Google Slab 占用高”的建议,通过 Google 得到了 slabtop 这条命令执行之后发现占用最高的是 dentry, google 后得到了这篇文章 记一次内存使用率过高的报警 从文中得知 “ nss-softokn 的 bug 导致 curl 大量请求后, dentry 缓存飙升”。服务器的监控模块,第三方接口对接的实现都是根据curl实现的,curl的使用确实很多。 根据文中的方法进行排查与修复,当时内存占用还是在 47G ,因为dentry是会自动清理的,所以没有进行手动了清理。现在内存使用已经下降到了 36G。

通过这次事件,深深的感受到了没有运维的痛苦之处,毕竟不是专业搞运维的。当然,下次遇到同样的情况的话也就会往这方面考虑了,遇到问题,解决问题,理解问题,在问题中得到提升。当然,再次感慨社区的力量与人性的善。