Cocos开发中性能优化工具介绍之Visual Studio内存泄漏检测工具Visual Leak Detector

来源:互联网 发布:淘宝库存软件 编辑:程序博客网 时间:2024/05/23 00:05

Cocos开发中性能优化工具介绍之Visual Studio内存泄漏检测工具Visual Leak Detector

微软提供 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(如果你的Windows操作系统是64位,则添加lib\Win64),注意配置目之间需要用分号分隔开。

这里写图片描述

配置完成之后点击确定按钮关闭对话框,然后我们需要在程序代码中引入头文件 #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 的安装信息(注意在程序结束以后才会一次性打印出所有相关 log ,注意:此处说的程序结束指的是点击窗口的关闭按钮来结束程序,如果你通过点击 VS 的 stop debugging 按钮来关闭程序的话,是不会打出相关 log 的),日志信息如下:

Visual Leak Detector Version 2.4RC2 installed.Ready for GLSLReady 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     ........ ........

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

这里写图片描述

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

0 0