内存泄漏的问题,在百度是遇到最多的,阿里相对少点。与内存泄漏斗争了很久,我总结下常用的一些有效测试方法吧。
1、valgrind,这是非常好用的工具,虽然参数很多,输出结果较多,但是只要认真看下,就很容易发现问题,报告是很详细的,不要被吓倒。valgrind检测的内存泄漏是非常准的,可以精确定位到代码行甚至是变量。valgrind基于valginrd core框架,这是个非常有强大的框架,他的作用不仅仅在于检测内存泄漏的,强烈建议测试新手通读下全部的文档。valgind自己也会有误报和漏报,所有具体场景需要具体分析。报告中一旦出现definitely lost的标记,就表示一定会有内存泄漏,泄漏的字节数也会报告出来,可以根据泄漏的内存大小和请求次数计算出到底是那个变量没有释放。
2、利用pmap+gdb,pmap可以列出特定进程的所有内存分配的地址和大小,通过gdb就可以直接看这些地址属于什么变量,通过统计这些内存地址的大小,就可以很容易的发现问题。利用自动化的gdb调试工具也可以很方便的定位。
3、其他的还包括memprof、商业工具Purify IBM出品,官方宣传说的不错,但是这种不开放的技术,在业界得不到认可,国内大公司一般那都不用,只有人傻钱多的公司在用。
4、利用一些trace工具,比如ptrace,strace之类的工具,这些trace工具会追踪特定的api,只需要统计malloc和free的调用次数就可以简单的发现是否有泄漏,但是无法定位代码行。另外还有一个更高深的工具,SystemTap,这个在国内应用还不多,但是非常厉害,可以方便hook程序的关键逻辑并插入探针。从而可以方便的检测内存泄漏。Systemtap目前还不通用,而且安装复杂,暂时不推荐使用,可以关注下,过几年可能会大规模应用。
valgrind是首选,因为他的设计就是为了解决所有的c++的内存问题。一些valgrind不能简单发现的,我一般会review代码,然后通过gdb自动调试技术来发现问题。通过valgrind+gdb,可以解决所有的内存泄漏。
另外,内存的泄漏也并不完全是没有及时的free,还有可能是其他的原因,比如设计问题等。需要靠一定的开发经验判断。
要尽量把静态测试和动态测试尽早的加入到持续集成中,以尽早的发现问题,不然一旦代码复杂,追查的成本就会增大。