首页 > 编程 > C > 正文

VisualStudio 使用Visual Leak Detector检查内存泄漏

2020-01-26 15:03:45
字体:
来源:转载
供稿:网友

那么在Windows下有什么好的内存泄漏检测工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检测功能,我们可以使用第三方工具Visual Leak Detector(以下简称vld)。

vld工具是VC++环境下一款小巧易用、免费开源的内存泄漏检测工具,vld可以显示导致内存泄漏的完整内存分配调用堆栈。vld的检测报告能够对每个内存泄漏点提供完整的堆栈跟踪,并且包含其源文件及行号信息。

安装过程是,先在到地址http://vld.codeplex.com/下载vld安装文件,然后进行安装,安装过程中需要安装程序会配置环境变量。我们需要记住安装目录。

安装完成后打开要检测的Visual Studio工程,我们需要在工程中配置:vld头文件目录和vld库目录。

选中游戏工程,打开菜单“项目”→ “属性”弹出工程属性对话框,如图所示,选择“配置属性”→“VC++目录” →“常规”,在右边的“包含目录”中添加C:/Program Files (x86)/Visual Leak Detector/include,其中C:/Program Files (x86)/Visual Leak Detector是我的vld安装目录。“库目录”中添加C:/Program Files (x86)/Visual Leak Detector/lib/Win32,注意配置目之间需要用分号分隔开。

配置完成之后点击确定按钮关闭对话框,然后我们需要在程序代码中引入头文件#include <vld.h>,但是这个头文件在哪里引入比较好?如果是普通的一个VC++工程在哪里引入都无所谓,但是Cocos2d-x的工程就不同了,我们需要考虑跨平台,#include <vld.h>代码不宜添加到Classes目录下的h或cpp文件中,这个目录下的文件是要在其它平台编译运行的,而#include <vld.h>只是在Windrows平台才有效。我们可以在Win32目录(见图)下的main.cpp或main.h文件引入头文件。这些文件是与Win32平台有关的,不同平台移植的时候不需要。

如果在main.cpp中引入代码如下:

#include "main.h" #include "AppDelegate.h" #include "cocos2d.h"   #include <vld.h>   USING_NS_CC;   int APIENTRY _tWinMain(HINSTANCE hInstance,             HINSTANCE hPrevInstance,             LPTSTR  lpCmdLine,             int    nCmdShow) {   UNREFERENCED_PARAMETER(hPrevInstance);   UNREFERENCED_PARAMETER(lpCmdLine);     // create the application instance   AppDelegate app;   return Application::getInstance()->run(); } 

引入之后,就测试一下了,我们来人为制造一个内存泄漏,与20.1.1一节一样在HelloWorldScene.cpp中修改代码:

bool HelloWorld::init() { if ( !Layer::init() ) { return false; }   __String *s = new __String();     log("%s",s->getCString());   … …   return true; } 

运行工程,需要注意的是在程序运行过程中vld是没有堆栈输出的,但是日志会有输出vld的安装信息,日志信息如下:

Visual Leak Detector Version 2.4RC2 installed.

Ready for GLSL

Ready for OpenGL 2.0

… …

从日志中可以看到vld是否安装成功,以及安装的版本。要想看到vld检测报告需要退出程序后,才会在日志中输出信息。使用Cocos2d-x会输出很多日志信息,信息如下:

---------- Block 526166 at 0x0821FA80: 84 bytes ---------- Leak Hash: 0x780B2033, Count: 1, Total 84 bytes Call Stack (TID 4660):... ...---------- Block 526214 at 0x08224378: 8 bytes ---------- Leak Hash: 0xE1DC1852, Count: 1, Total 8 bytes Call Stack (TID 4660):... ... Data:  63 6F 63 6F  73 32 64 20  61 75 74 6F  72 65 6C 65   cocos2d. autorele  61 73 65 20  70 6F 6F 6C  00 CD CD CD  CD CD CD CD   ase.pool ........Visual Leak Detector detected 33 memory leaks (2892 bytes).Largest number used: 3204961 bytes.Total allocations: 69022415 bytes.Visual Leak Detector is now exiting.

其中一个Block表示一个内存泄漏点,在众多Block如果能够找到关于我们自己类的日志信息呢?我们可以查找关键字“helloworldscene.cpp”,这就可以定位到HelloWorld场景中的内存泄漏的Block了,我们找到如下日志信息:

---------- Block 1153 at 0x01533C70: 48 bytes ---------- Leak Hash: 0x5545A5ED, Count: 1, Total 48 bytes Call Stack (TID 2088):  f:/dd/vctools/crt_bld/self_x86/crt/src/new.cpp (57): MSVCR110D.dll!operator new  d:/helloworld/classes/helloworldscene.cpp (33): HelloWorld.exe!HelloWorld::init + 0x7 bytes  d:/helloworld/classes/helloworldscene.h (37): HelloWorld.exe!HelloWorld::create + 0xB1 bytes  d:/helloworld/classes/helloworldscene.cpp (12): HelloWorld.exe!HelloWorld::createScene + 0x5 bytes  d:/helloworld/classes/appdelegate.cpp (30): HelloWorld.exe!AppDelegate::applicationDidFinishLaunching + 0x5 bytes  d:/helloworld/cocos2d/cocos/2d/platform/win32/ccapplication.cpp (74): HelloWorld.exe!cocos2d::Application::run + 0xF bytes  d:/helloworld/proj.win32/main.cpp (19): HelloWorld.exe!wWinMain + 0xC bytes  f:/dd/vctools/crt_bld/self_x86/crt/src/crtexe.c (528): HelloWorld.exe!__tmainCRTStartup + 0x15 bytes  f:/dd/vctools/crt_bld/self_x86/crt/src/crtexe.c (377): HelloWorld.exe!wWinMainCRTStartup  0x7563850D (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes  0x77B7BF39 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x85 bytes  0x77B7BF0C (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x58 bytes Data:  1C 34 07 01  01 00 00 00  27 00 00 00  00 00 00 00   .4...... '.......  2C 34 07 01  A0 77 01 03  00 CD CD CD  CD CD CD CD   ,4...w.. ........  CD CD CD CD  CD CD CD CD  00 00 00 00  0F 00 00 00   ........ ........

从这个日志中能看到内存泄漏点,从日志的堆栈中找到我们自己编写的类,点击那一行打开代码窗口,定位内存泄漏点代码,如图所示。

定位内存泄漏点

找到哪一个有可能有内存泄漏,解决就不是问题了。

以上所述就是本文的全部内容了,希望大家能够喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选