那么在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 ........ ........
从这个日志中能看到内存泄漏点,从日志的堆栈中找到我们自己编写的类,点击那一行打开代码窗口,定位内存泄漏点代码,如图所示。
定位内存泄漏点
找到哪一个有可能有内存泄漏,解决就不是问题了。
以上所述就是本文的全部内容了,希望大家能够喜欢。
新闻热点
疑难解答
图片精选