如何处理大型 C++程序的内存泄露问题

2015-07-29 19:58:51 +08:00
 matthewgao

程序在一个月的运行中不断吃内存,一个月吃掉了32G的内存,但是线上系统还不能停,不能改配置。。。。 有什么好办法排除内存泄露的问题么?

2067 次点击
所在节点    C
31 条回复
linxy
2015-07-29 20:01:45 +08:00
换go
matthewgao
2015-07-29 20:03:35 +08:00
@linxy 不现实。。。
acros
2015-07-29 20:11:43 +08:00
占个座位等解答。
这种环境下,是不是只能靠内存dump分析了?
fo2w
2015-07-29 20:15:32 +08:00
看描述我完全不知道你是要解决问题还是排查问题
不停机不能改配置要解决问题那无解, 或者我太废柴暂时没想到办法
要查问题这种情况下钩子就好了

但是...我还是建议好好review一遍代码...
这种泄漏量肉眼我真不信看不出来
sinxccc
2015-07-29 20:16:13 +08:00
我们常用的做法是首先复制一个尽可能跟在线系统一样的环境,然后如果性能说得过去的话用 valgrind 跑可疑进程,对性能要求高的话,加上自己包装过的 new/delete/malloc/free 然后跑一段时间看输出的统计。

分离出最可疑的地方之后再按照这个特征走查代码。
lijianying10
2015-07-29 20:20:45 +08:00
不知道是何种业务,
1. 取一份程序拷贝准备复现问题
2. 两个方面来确定问题的来源
1. 用更高的业务访问频率(业务参数)来模拟在线程序的情况,让问题显现更清楚
2. 满足上面一条之后,(如果是巨大循环的算法)每次注释掉一个模块,来排查问题。找到是那个大模块之后,再从大模块入手使用同样方法,直到找到泄露点。
1. 尽量避免注释掉依赖模块。从底层开始。
2. 模块的划分粒度大小很重要,影响排查速度
3. 如果是由独立业务堆砌出来的大型程序,要从业务划分来找到一个或者多个业务发生泄露,然后使用上面的方法
4. 如果十分确定使用上面两条找不到。最后一招CodeReview。
5. 找到来源之后修复一下,做项目回归测试。

希望此流程能帮到楼主。这也是我在做计算程序的时候排查泄露时候的方法。
ch3n2k
2015-07-29 20:32:34 +08:00
加大swap,让它泄漏去。话说什么程序不能停机啊?要改架构啊
typcn
2015-07-29 20:42:31 +08:00
@ch3n2k 内存泄露只是丢失访问途径,而且还非常容易造成程序的崩溃,仅仅占内存的话,那叫内存申请不合理,没有释放

还是用 valgrind 跑吧,手找累死人
zhouc
2015-07-29 22:03:47 +08:00
你们的程序是server程序,不能load balance traffic?
jedihy
2015-07-29 22:16:44 +08:00
对,valgrind,差不多就这些办法。一般单元测试的时候就要按模块找出内存泄露,不然耦合到一起很难找了。
lsmgeb89
2015-07-29 22:25:29 +08:00
大型的 C/C++ 程序,一开始开始就要考虑到内存管理模块啊,团队要制定好内存使用的规则,这样出现内存泄漏就可以定位到那个 instance 和代码位置。

PS:用 Valgrind 跑很慢的,而且不一定能够定位的。
xylophone21
2015-07-29 22:38:08 +08:00
#define new(x) mynew(__FILE__,__LINE__,x);
signifox
2015-07-29 23:32:04 +08:00
gcc4.8以上版本用[AddressSanitizer]{https://code.google.com/p/address-sanitizer/wiki/AddressSanitizer},
低版本的用[efence]{https://directory.fsf.org/wiki/Electric_Fence}

检查C++内存泄露的神器。
alphonsez
2015-07-30 00:07:20 +08:00
建议改成能重启的。老不能重启总是个麻烦,总不见得永远不部署吧?如果能重启就好办了,每天重启一次呗。
akira
2015-07-30 00:59:37 +08:00
如果有完善的日志的话,可以试试从日志里分析出业务量变化和内存增加变化的关系。定位到业务的话 就比较好做代码review了
dndx
2015-07-30 01:07:21 +08:00
用智能指针。
JamesRuan
2015-07-30 02:01:11 +08:00
上Erlang/OTP
vietor
2015-07-30 08:16:50 +08:00
所有内存分配回收代码都过一遍, 尤其用指针封装的地方(智能指针,共享指针),许多人没理解就乱用,用错。我之前就将所有智能指针转成自写封装类,解决内存泄漏
nightv2
2015-07-30 09:43:08 +08:00
重启啊,至少能改善问题,然后排查是那个模块
qyz0123321
2015-07-30 09:50:33 +08:00
智能指针是王道

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/209368

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX