在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中引入代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include"main.h"
#include"AppDelegate.h"
#include"cocos2d.h"
#include<vld.h>
USING_NS_CC;
int
APIENTRY_tWinMain(
HINSTANCE
hInstance,
hPrevInstance,
LPTSTR
lpCmdLine,
nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//createtheapplicationinstance
AppDelegateapp;
return
Application::getInstance()->run();
}
|
引入之后,就测试一下了,我们来人为制造一个内存泄漏,在HelloWorldScene.cpp中修改代码:
bool
HelloWorld::init()
{
if
(!Layer::init())
{
return
false
;
}
__String*s=
new
__String();
log
(
"%s"
,s->getCString());
……
true
;
运行工程,需要注意的是在程序运行过程中vld是没有堆栈输出的,但是日志会有输出vld的安装信息,日志信息如下:
|
----------Block1153at0x01533C70:48bytes----------
LeakHash:0x5545A5ED,Total48bytes
CallStack(TID2088):
f:\dd\vctools\crt_bld\self_x86\crt\src\
.cpp(57):MSVCR110D.dll!operator
new
d:\helloworld\classes\helloworldscene.cpp(33):HelloWorld.exe!HelloWorld::init+0x7bytes
d:\helloworld\classes\helloworldscene.h(37):HelloWorld.exe!HelloWorld::create+0xB1bytes
d:\helloworld\classes\helloworldscene.cpp(12):HelloWorld.exe!HelloWorld::createScene+0x5bytes
d:\helloworld\classes\appdelegate.cpp(30):HelloWorld.exe!AppDelegate::applicationDidFinishLaunching+0x5bytes
d:\helloworld\cocos2d\cocos\2d\platform\win32\ccapplication.cpp(74):HelloWorld.exe!cocos2d::Application::run+0xFbytes
d:\helloworld\proj.win32\main.cpp(19):HelloWorld.exe!wWinMain+0xCbytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c(528):HelloWorld.exe!__tmainCRTStartup+0x15bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c(377):HelloWorld.exe!wWinMainCRTStartup
0x7563850D(Fileandlinenumbernotavailable):KERNEL32.DLL!BaseThreadInitThunk+0xEbytes
0x77B7BF39(Fileandlinenumbernotavailable):ntdll.dll!RtlInitializeExceptionChain+0x85bytes
0x77B7BF0C(Fileandlinenumbernotavailable):ntdll.dll!RtlInitializeExceptionChain+0x58bytes
Data:
1C340701010000002700000000000000.4......'.......
2C340701A077010300CDCDCDCDCDCDCD,4...w..........
CDCDCDCDCDCDCDCD000000000F000000................
|
从这个日志中能看到内存泄漏点,从日志的堆栈中找到我们自己编写的类,点击那一行打开代码窗口,定位内存泄漏点代码,如图所示。
定位内存泄漏点
找到哪一个有可能有内存泄漏,解决就不是问题了。