如何应对内存泄露

日期:2015-04-03点击次数:9186

内存泄露是程序开发过程中一个令人头疼的问题,不过现在有很多的技术被研究出来监控内存,首先来总结下内存泄露的产生及方式:
内存泄露一般是指堆内存的泄露,堆内存一般是由程序员手动开辟的任意大小的内存块,常常使用的函数为malloc,realloc,new,alloc等函数从堆栈中分配一块内存,在使用完后,相应的调用free,delete,delete[]等来释放内存,但是往往在开辟完内存后没有正确的释放内存而导致内存的泄露。堆内存泄露是最常见的一种,除此之外,系统资源(比如句柄,socket等)在分配后不销毁也会消耗内存。当一个进程存在严重的内存泄露时会导致该应用程序崩溃,更甚者是操作系统的不响应或者挂掉。在前不久的测试中,发现网页插件客户端总是不响应,通过检测性能,发现因为内存的占用过大而导致进程崩溃,内存泄露的问题不容忽视。
在此介绍一款在windows下检测程序的性能的工具:Process Explorer。这个小工具可以很详细的检测应用程序的所有状态,包括应用程序所关联的库文件,对于CPU,内存,I/O,线程,TCP/IP,GPU等都很直观详细。
本文中我挑选一个我曾经使用过的内存检测工具进行介绍,即linux下的内存检测工具Valgrind。Valgrind是一款用于内存调试,内存泄露检测及性能分析的软件开发工具,其安装步骤很简单,在官网上下载valgrind-3.9.0.tar.bz2后,使用如下的命令进行解压安装:
tar –xvf valgrind-3.9.0.tar.bz2
cd valgrind-3.9.0
./configure
make
make install
执行完上述命令后即可使用,我一般在安装完文件后,会确定时候安装成功,可以通过valgrind –version来查看valgrind的版本号来确认。
   Valgrind其中包括好多个工具,我主要使用到的是memcheck工具,它可以检查一些程序的错误,比如:使用未初始化的内存(Use of uninitialized memory)、使用已释放的内存(Reading/writing memory after it has been free)、使用的内存越界(Reading/writing off the end of malloc blocks)、对堆栈的非法访问(Reading/writing inappropriate areas on the stack)、申请的空间是否释放(Memory leaks where pointers to malloc block are lost forever)、申请和释放的内存的匹配等。
Memcheck工具所能检查的错误几乎包括了所有内存泄露的情况,接着说明使用命令:
Valgrind –tool=memcheck –leak-check=yes –show-reachable=yes  ./可执行程序名。
当命令执行后,出打印出监测的结果,当初测试的时候首先选择的是一个简单的小例子进行的,给出的检测信息很具体清晰,于是很兴奋的将该工具用于我们自己的程序进行检测,由于我们的应用程序的工程庞大,自身的源文件和头文件就很多,还调用了很多的库文件,于是在检测时给出的检测信息也是相当的庞大,其中很多的检测信息是定位到调用的库文件中,于是查看分析整个检测文件也成了头疼的事情。
虽然valgrind给出了很多的检测信息,但是却无法很快的找到内存泄露的原因。尽管这个结果不是我想要的,但是也给我在开发过程中提供了帮助,让我总结工作中的得失,如果在工程还比较瘦小的时候就开始就利用这个工具进行检测,肯定会给工作带来帮助。现如今要查找一个大的工程文件中的内存泄露,就必须要依靠对于代码逻辑的严格审查,对于各种异常情况有个周密的处理。
工作中虽然有很多的工具可以利用,巧妙的使用工具可以提高工作效率,改善性能,但最根本最重要的还是要有严谨的逻辑思维。





研发部         陈娟