现场现象
长期运行的服务每天较大概率出现内存膨胀
,导致发生oom,os把服务杀死。此现象十分令人头疼。
原因猜测分析
- 当作内存泄漏去查,用valgrind挂上,连续好几天,结果都显示无内存泄露。令人十分困惑,但是内存却真真切切的在膨胀
- 考虑glibc
站岗
问题,采用定时 malloc_trim(0),强制刷新释放glibc带给进程的内存池,结果也和预期一样,无效。
柳暗花明
分析陷入阻塞,一筹莫展。偶然听说bcc工具集,很多有用的工具。此次主角就是bcc/memleak
Memleak跟踪和匹配内存分配和回收请求,并为可以显示调用堆栈。可以通过命令行控制采集信息的输出。
上图中发生了巨大内存分配,对于debug
程序来说, 绝大多数调用堆栈是可以打印出来的,但是上图中却没有
最后结论
- 程序异常分配大内存,且没有释放,但不知道在哪产生的
- 但是有明确的地址和大小,意味着可以用gdb dump出大内存块,用来分析
- 绝大多数程序都会包含可视化字符,因为程序是为人服务的, 所以利用strings可以从内存数据中看出端倪
通过分析定位,最终发现内存膨胀是因为特定场景下,发生丢包,导致程序解析数据长度异常,同时程序利用std::string作为buf,string异常扩容导致。
到此,valgrind疑云也解释了,因为STL容器的内存相关 不属于真正意义上的内存泄漏
,故而有个新名字,文章title中的 内存膨胀