这篇文章主要介绍了VisualStudio 使用Visual Leak Detector检查内存泄漏的相关资料,需要的朋友可以参考下
那么在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 ,但是这个头文件在哪里引入比较好?如果是普通的一个VC++工程在哪里引入都无所谓,但是Cocos2d-x的工程就不同了,我们需要考虑跨平台,#include 代码不宜添加到Classes目录下的h或cpp文件中,这个目录下的文件是要在其它平台编译运行的,而#include 只是在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 ........ ........
从这个日志中能看到内存泄漏点,从日志的堆栈中找到我们自己编写的类,点击那一行打开代码窗口,定位内存泄漏点代码,如图所示。
定位内存泄漏点
找到哪一个有可能有内存泄漏,解决就不是问题了。
以上所述就是本文的全部内容了,希望大家能够喜欢。
新闻热点
疑难解答