在测试自己写的程序时,我们一般都会去任务管理器查看程序内存状况,看内存是否随着时间一直增长,如果一直增长,那恭喜了,程序内存泄露了。
编写程序时要养成良好习惯,申请的内存要记得释放,遇到内存泄露时要认真查看申请的内存释放了没,除此之外,我们也可以通过第三方帮助我们发现程序内存泄露状况。
_CrtDumpMemoryLeaks函数
系统自带的 C Run-Time (CRT)库可以帮助我们检测内存泄露,使用很简单。
1)包含相应头文件
1 2 3 |
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> |
2)在程序退出地方,加上:
1 |
_CrtDumpMemoryLeaks(); |
在调用_CrtDumpMemoryLeaks函数前我们要确保释放了该释放的内存,最后程序结束后在Output窗口就会打印出内存泄露信息。
3)如果我们程序有多个退出点,需要都添加上_CrtDumpMemoryLeaks函数,比较麻烦,此刻_CrtSetDbgFlag 函数就比较方便了。在程序初始化地方加上:
1 |
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); |
这个函数会在我们程序每个退出点自动执行_CrtDumpMemoryLeaks 函数。
对于如何定位内存泄露代码以及其他使用,可以看下MSDN上的介绍:https://msdn.microsoft.com/en-us/library/x98tx3cf.aspx。
Visual Leak Detector(VLD)插件
给我们的VS装上该插件,下载地址:https://vld.codeplex.com/,使用方法很简单,安装完插件后,在我们要检测的文件加上
1 |
#include <vld.h> |
然后在debug模式下运行,在Output窗口即可查看详细泄露信息,其实该插件原理就是上一节说到的CRT库。比如我们下面一段测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include<iostream> #include <vld.h> void LeakTest() { char *memory = new char[10]; int a = 10; memcpy(memory, &a, sizeof(a)); /*if (nullptr != memory) { delete[] memory; memory = nullptr; }*/ } int main() { LeakTest(); return 0; } |
上述代码我们注释掉了delete部分,debug运行结束后我们可以看到Output窗口显示泄露了10字节,同时打印出泄露的堆栈,如果程序复杂的话,我们可以在Output窗口双击泄露的堆栈定位到相应代码。
VS2015内存快照
在VS2015引入了强大的内存查看工具,在程序运行时,右侧窗口我们可以查看程序内存状况。通过截取某两个不同时刻的内存快照,进行对比,可以快速找到泄露部分。同样还是上面的测试代码,不过得注释掉include vld头文件这一行,我们按如下步骤定位泄露部分。
1)在LeakTest处打个断点,debug运行,在右侧窗口->Memory Usage标签页中启用Heap Profiling。
2)点击Take Snapshot,相当于一次拍照(这图标就是一个相机),此刻下面即可显示当前分配的内存大小,堆大小。
3)执行完测试函数后,我们再次点击Take Snapshot按钮,此刻提示了与上一次快照的变化。
4)点击括号处(+1)或(+0.04KB)变化部分链接。
5)在左侧窗口查看与前一次快照对比,具体什么数据造成内存变化。
6)双击后查看定义为char类型数据的具体实例,我们程序中只定义了一个char类型数据,所以只有一个实例,再双击某个实例可以定位到具体代码,同时查看相应堆栈调用,由于测试程序太简单了,所以这里看不到。
拿我以前写的一个复杂程序举例,程序中我定义了多个CString类型数据,点击查看CString数据具体实例。
我们可以看到多个CString数据实例,点击某个实例就可以看到堆栈调用了,双击具体的堆栈调用可以定位到具体代码。
详细使用可以参考微软官方博客:https://blogs.msdn.microsoft.com/vcblog/2015/10/21/memory-profiling-in-visual-c-2015/,我就不细说了。
文章评论
技术牛人,您好,Wondershare公司正在招聘C++研发牛人,为中国软件筑梦,如果您感兴趣一起加入其中,可以试用邮箱联系。期待您的回复。https://www.wondershare.cn/