今天,在运行目前正在维护的产品后,我发现产品在跑完个别的测试用例后,出现了大量的内存泄漏。从visual studio 2008
的输出中看不到具体是哪个文件的new
操作引起,在DEBUG
版本中看不到是由哪个new
分配的内存泄漏的原因是文件中没有如下的宏。
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
由于项目中的文件较多,如果到一个一个文件中去找,那是件枯燥而且乏味的工作, 而且难保不会有遗漏。所以我编写了脚本来报告没有这几句的文件。
通过在文件中加上了上述的宏,我再次重新运行刚才产生内存泄漏的测试用例。这次我定位了泄漏的内存分配语句。所以为了调试上的方便,我们应保证文件中有如上的宏。找到了相关的分配语句就离解决这个错误近了,现在就是要找出遗漏的释放点。
为了使用我以前安装的共享版内存泄漏检测工具,我将系统的时间改成6月份。可惜还是提示过了试用期不让使用,所以还得靠自己。通过查阅代码,找出了几个可疑点,分别加上了恰当的语句,按一下build 后,刚巧有事就离开了。回来后发现看看没有编译错误,于是再测试用例,结果还是出现泄漏。于是我加上调试断点来分析,可是程序根本不在断点处停止。这让我着实惊讶,难道程序并不经过这些断点? 再放置几个断点,依然不停住,最后就在InitInstance()函数中放一断点,可还是不停住。这时我才恍然大悟这个exe文件与代码不一致。于是改回系统时间,重新build。再次运行,程序在断点处停住,运行相应的测试用例,也不再有内存泄漏。
在这个过程中,由于visual studio的编译行为所采用的时间比较来决定编译的行为及本人的粗心让我浪费了一些时间和精力。这也提示我们在设计软件时,对于优化行为应多加考虑,行为的优化是否符合了用户的企图,如果与用户的动作不符合,则应给用户提示并得到用户的指示。