定位一个服务内存占用率过高的问题:
起因
机器报警,内存不足,用free命令去看,看到内存不足
用top 然后M按内存使用率排序,找到服务的进程号
top -p 进程号
看到这个进程占用了1.5G的虚拟内存
分析
|
|
VmStk 栈区大概688KB还ok
看到VmData占了将近1G大小,google了一下VmData介绍说是堆区
把代码遍历了一遍,找到所有new的地方,看看有没有delete,排除了内存泄漏的情况
然后在代码中print了一把所有的new的类 cout<<sizeof(classname)<<endl;
看到这些类加起来也就100KB,一共100个微线程加起来也就10MB的样子
进一步分析
这时候就纠结了
问了几个老同事,提供了些新的思路:
- 内存泄漏,已经排除过,而且程序刚启动就占用了很大的内存大小
- 把微线程限制到1个,在程序运行过程中,打印内存使用情况
解决
这时候有个以前搞安全的同事帮忙一起看了:
cat /proc/29912/smaps
看看https://blog.csdn.net/tangtang_yue/article/details/78298067
smaps文件中,每一条记录表示进程虚拟内存空间中一块连续的区域
其中权限标识,rw-s表示可读可写的共享内存,rw-p表示可读可写的私有
还可以在里面搜索heap和stack,应该有多块连续区域,可以累加得到堆栈的大小
进一步在这个文件里搜索:
看到最大的一块区域:
5249 7fb495e28000-7fb49c228000 rw-s 00000000 00:04 1277991 /SYSV10910931 (deleted)
5250 Size: 102400 kB
/SYSV10910931 表示是一个共享内存
在/proc目录下,grep -rni “SYSV10910931” ./*/smaps
看到所有使用这块共享内存的进程
然后一个个单独 top -p 进程
判断一下哪个进程是最后可能创建这个共享内存的