1、下载地址:http://www.technlg.net/windows/windgb-download/
注意:最好下载x64位的安装包,因为32位的安装包可能会安装不成功。
2、环境配置
计算机-》右击-》属性-》高级系统设置-》环境-》系统变量-》Path-》编辑-》变量值 处后加入:
c:\Program Files\Debugging Tools for Windows(x64)
注意:此路劲请参考个人的安装路径。
3、利用工具umdh(user-mode dump heap)分析
(1)由于在安装路径下有 gflags.exe、umdh.exe 这两个可执行文件,且在步骤2中已加入环境变量,下一步可直接在dos界面输入命令;
(2)桌面左下角-》开始 处输入cmd命令,打开dos界面窗口后,输入命令:gflags.exe,会出现下图,并按照下图进行相关设置:
(3)gflags标志设置好后,开启cmd
键入要定位内存泄露的程序gflags.exe /I memroyleak.exe(程序名称)+ust
如图成功后,开启memoryleak.exe程序,即运行需要测试的程序。
4、利用umdh创建heap快照
命令格式:umdh–pn:memoryleak.exe(程序名称) –f:snap1.log(日志名称)
程序运行一段时间后或者程序占用内存增加时,将memoryleak.exe退出。
然后再次创建heap快照,命令行无差别,snap1.log改为snap2.log或者其他。
设置好程序的符号路径,如下图:
设置好后可以开始分析heap前后两个快照的差异
分析差异命令:umdh –d snap1.log snap2.log –f:result.txt
分析完成后查看结果result.txt,可以指定具体的输出文件夹,不指定的话,输出在桌面的个人文件夹《以自己名字命名的文件夹》
红色为umdh定位出来的泄露点,我们在查看源代码
这样我们就可以修改代码中内存泄露的地方了。
注意:利用Umdh创建Heap快照 步骤设置程序的符号路径,此符号路径是一个在线网址,因此需要电脑联网;对于我们来说只能通过下载符号离线包的方式,离线包的路径为:
https://developer.microsoft.com/en-us/windows/hardware/download-symbols
关键词:Download Windows Symbol Packages
但是不下载此包,符号路径会自动设置为 %windir%\symbols 即windows自带的符号路径,目前未发现问题
参考网址:http://blog.csdn.net/chenyujing1234/article/details/11918987
windows下内存泄漏--新大陆
1、检测是否存在内存泄漏
Windows平台下面Visual Studio 调试器和C运行时(CRT)库为我们提供了检测和识别内存泄漏的有效方法,原理大致如下:内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。在vs中启用内存检测的方法如下:
(1)、程序文件开头处包含以下语句,不要更改顺序
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
通过包括crtdbg.h,将malloc和free函数映射到它们的调试版本,即_malloc_dbg和 _free_dbg,这两个函数将跟踪内存分配和释放。 此映射在调试版本(在其中定义了_DEBUG)中发生。 发布版本使用普通的 malloc 和 free 函数。
#define 语句将 CRT 堆函数的基版本映射到对应的“Debug”版本。 并非绝对需要该语句;但如果没有该语句,内存泄漏转储包含的有用信息将较少。
(2)、在添加了上述语句之后,可以通过在程序中包括以下语句(通常应恰好放在程序退出位置之前)来转储内存泄漏信息:
_CrtDumpMemoryLeaks();
示例代码:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main(int argc,char** argv)
{
char *str = (char*)malloc(20 * sizeof(char));
_CrtDumpMemoryLeaks();
return 0;
}
当在调试器下运行程序时(按F5),_CrtDumpMemoryLeaks将在VS最下栏 “输出”窗口 -》显示输出来源-》调试 中显示内存泄漏信息。如果没有使用#Define _CRTDBG_MAP_ALLOC语句,输出窗口则不显示内存泄漏的具体位置。
注意:
如果程序总是在同一位置退出,调用 _CrtDumpMemoryLeaks 将非常容易。如果程序从多个位置退出,则无需在每个可能退出的位置放置对 _CrtDumpMemoryLeaks 的调用,而可以在程序开始处包含以下调用:
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
该语句在程序退出时自动调用 _CrtDumpMemoryLeaks。必须同时设置 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF两个位域。
示例代码:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main(int argc,char** argv)
{
char *str = (char*)malloc(20 * sizeof(char));
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
return 0;
}
或
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
void check_mem()
{
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
}
int main(int argc,char** argv)
{
char *str = (char*)malloc(20 * sizeof(char));
atexit(check_mem);
return 0;
}
注:上述方法在测试调用的第三方库是否存在内存泄漏时,并不能显示泄露函数在哪个文件、哪一行,只会简单的显示,如:
Detected memory leaks!
Dumping objects ->
{223} normal block at 0x003CF650, 4 bytes long.
Data: < < > E8 F6 3C 00
此时,需要在程序的入口处加入:
_CrtSetBreakAlloc(223);
在vs中按F5调试,在堆栈信息中就可以看到泄露的具体位置。其中
223表示
{223} normal block at 0x003CF650, 4 bytes long.
参考网址:https://msdn.microsoft.com/en-us/library/x98tx3cf.aspx