在网上看了两篇文章,整理一下,大致内容如下:

场景一:运行Debug版本程序,用Windbg attach 上去,等程序退出时,基于内存泄露报告,定位内存泄露的位置。

首先使用windbg工具gflags.exe设置内存启动跟踪内存泄露进程的user stack
启动方法就是运行下面指令<span style="BACKGROUND-COLOR: #ff6666">gflags.exe /i test.exe +ust</span><span style="BACKGROUND-COLOR: #ffffff"> <span style="color:#ff0000;">需要通过gflags.exe工具打开开关,才能调试内存泄露!
</span>
</span>等价于HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options,命令“gflags.exe /i test.exe +ust”实际上就是在该路径下创建一个子键“test.exe”并创建一个名为GlobalFlag内容为0x00001000的REG_DWORD值。
使用windbg加载test.exe,运行关闭时windbg中会提示内存泄露
normal block at 0x026A5F98, 4000 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
可以发现地址0x026A5F98就是内存泄漏的地址泄漏4000个字节
通过!heap命令对该地址进行分析可以发现具体的调用堆栈
0:000> <span style="BACKGROUND-COLOR: #ff99ff">!heap -p -a 0x026A5F98
</span>    address 026a5f98 found in
_HEAP @ 14f0000
HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
026a5f60 01fc 0000  [00]   026a5f78    00fc4 - (busy)
77a1b234 ntdll!RtlAllocateHeap+0x00000274
584d7743 MSVCR100D!_heap_alloc_base+0x00000053
584e5d8c MSVCR100D!_heap_alloc_dbg_impl+0x000001fc
584e5b2f MSVCR100D!_nh_malloc_dbg_impl+0x0000001f
584e5adc MSVCR100D!_nh_malloc_dbg+0x0000002c
584e5a91 MSVCR100D!_malloc_dbg+0x00000021
58694dd6 mfc100ud!operator new+0x00000026
58694e6a mfc100ud!operator new[]+0x0000001a
58694768 mfc100ud!operator new[]+0x00000018
*** WARNING: Unable to verify checksum for SendMsgEx.exe
2a3c25 <span style="BACKGROUND-COLOR: #ff99ff">SendMsgEx!CSendMsgExDlg::Thread1Proc</span>+0x00000055
767c1174 kernel32!BaseThreadInitThunk+0x0000000e
779fb3f5 ntdll!__RtlUserThreadStart+0x00000070
779fb3c8 ntdll!_RtlUserThreadStart+0x0000001b
可以发现内存泄漏的地址在CSendMsgExDlg::Thread1Proc这个地址里面调用了new[]导致内存泄漏
DWORD WINAPI CSendMsgExDlg::Thread1Proc(__in  LPVOID lpParameter)
{
INT *pVal = new INT[1000];
//..................
}

结论:场景一适用于Debug版本程序,而且需要在程序退出时才能定位泄露。

场景二:程序运行一段时间,用Windbg attach上去,查看堆内存使用情况;detach 让程序继续运行;过一段时间再 attach,查看堆内存使用情况,与第一次对比,找到内存明显增长的堆

我们开发的系统需要在客户的电脑上持续运行,可是客户报告在运行几天后,程序会占用越来越多的内存,最后会产生下面的两个错误使之不能继续:
1. The application has no enough resource to display
2. The application crash with a log like "memory allocation failed".
怎么办?上windbg。
准备工作
Configure the symbol file path to the Microsoft symbol server “SRV*c:\symbols*http://msdl.microsoft.com/download/symbols”,也可以一个环境变量_NT_SYMBOL_PATH到系统路径下,省得每次配置它
Add your program EXE/DLL PDB (program database) path to the symbol file path.(<span style="color:#ff0000;">设置PDB路径</span>)
Configure the Operating System's flag to enable user stack trace for the process which has memory leaks.
Gflags.exe -i excel.exe +ust(<span style="color:#ff0000;">和场景一一样,设置gflags.exe启动调试</span>)
第一次记录
让系统<span style="BACKGROUND-COLOR: #ff99ff">运行一段时间,用windbg attach 它的进程</span>,运行下面的命令
0:025> <span style="BACKGROUND-COLOR: #ff99ff">!heap -s
</span>LFH Key                   : 0xeaafe2e0
Heap     Flags   Reserv Commit Virt   Free List   UCR Virt Lock Fast
(k)     (k)    (k)     (k) length      blocks cont. heap
-----------------------------------------------------------------------------
00160000 00000002   32768 28204 28492   1460   239    19    0      f   LFH
00260000 00001002      64     40     40      3     1     1    0      0   L
00270000 00008000      64     12     12     10     1     1    0      0
004e0000 00000002      64      8      8      0     0     1    0      0   L
00030000 00001002    1088     72     72      9     2     1    0      0   L
00480000 00001002    7232   3444   3444     36     5     2    0      0   L
004c0000 00001002    1088    252    252      5     1     1    0      0   L
004d0000 00001002      64     12     12      4     1     1    0      0   L
01060000 00001002      64     16     16      2     2     1    0      0   L
01120000 00000002    1024     24     24      0     0     1    0      0   L
010b0000 00001002     256     32     32      0     0     1    0      0   L
01660000 00001002    3136   2796   2828    377    13     7    0      0   L
External fragmentation 13 % (13 free blocks)
01680000 00001002      64     32     32      3     0     1    0      0   L
01690000 00041002     256     12     12      0     0     1    0      0   L
01790000 00001003     256    104    116     60     9     3    0    bad
017d0000 00001003     256      4      4      2     1     1    0    bad
01810000 00001003     256      4      4      2     1     1    0    bad
030d0000 00001003     256      4      4      2     1     1    0    bad
03110000 00001003     256      4      4      2     1     1    0    bad
01850000 00001002      64     20     20      2     1     1    0      0   L
03560000 00001002    1280    664    776     22     7     4    0      0   L
04780000 00001003     256      8      8      2     1     1    0    bad
047c0000 00001003     256      4      4      2     1     1    0    bad
04800000 00001003     256      4      4      2     1     1    0    bad
04840000 00001003     256      4      4      2     1     1    0    bad
04880000 00001003     256      4      4      2     1     1    0    bad
048e0000 00001002     256     16     16      4     1     1    0      0   L
<span style="color:#000000;BACKGROUND-COLOR: #ff9900">04920000 00001002    1088   1012   1024    111     7     3    0      0   L
</span>04930000 00001002    3136    940    940    153     9     2    0     8d   L
04ce0000 00001002      64     16     16      0     0     1    0      0   L
04cf0000 00001002    1088    192    192      6     2     1    0      0   L
05850000 00001002      64     28     28      1     1     1    0      0   L
05de0000 00001002      64     12     12      3     1     1    0      0   L
第二次记录
Detatch the windbg from the excel process(<span style="color:#ff0000;">windbg 和 应用程序detach, 如果不detach,程序被中断到调试状态,无法运行</span>)
让它再运行一段时间,用windbg attach 它的进程,运行下面的命令
0:025> !heap -s
LFH Key                   : 0xeaafe2e0
Heap     Flags   Reserv Commit Virt   Free List   UCR Virt Lock Fast
(k)     (k)    (k)     (k) length      blocks cont. heap
-----------------------------------------------------------------------------
00160000 00000002   32768 28204 28492   1460   239    19    0      f   LFH
00260000 00001002      64     40     40      3     1     1    0      0   L
00270000 00008000      64     12     12     10     1     1    0      0
004e0000 00000002      64      8      8      0     0     1    0      0   L
00030000 00001002    1088     72     72      9     2     1    0      0   L
00480000 00001002    7232   3444   3444     36     5     2    0      0   L
004c0000 00001002    1088    252    252      5     1     1    0      0   L
004d0000 00001002      64     12     12      4     1     1    0      0   L
01060000 00001002      64     16     16      2     2     1    0      0   L
01120000 00000002    1024     24     24      0     0     1    0      0   L
010b0000 00001002     256     32     32      0     0     1    0      0   L
01660000 00001002    3136   2796   2828    377    13     7    0      0   L
External fragmentation 13 % (13 free blocks)
01680000 00001002      64     32     32      3     0     1    0      0   L
01690000 00041002     256     12     12      0     0     1    0      0   L
01790000 00001003     256    104    116     60     9     3    0    bad
017d0000 00001003     256      4      4      2     1     1    0    bad
01810000 00001003     256      4      4      2     1     1    0    bad
030d0000 00001003     256      4      4      2     1     1    0    bad
03110000 00001003     256      4      4      2     1     1    0    bad
01850000 00001002      64     20     20      2     1     1    0      0   L
03560000 00001002    1280    664    776     22     7     4    0      0   L
04780000 00001003     256      8      8      2     1     1    0    bad
047c0000 00001003     256      4      4      2     1     1    0    bad
04800000 00001003     256      4      4      2     1     1    0    bad
04840000 00001003     256      4      4      2     1     1    0    bad
04880000 00001003     256      4      4      2     1     1    0    bad
048e0000 00001002     256     16     16      4     1     1    0      0   L
<span style="BACKGROUND-COLOR: #ff6600">04920000 00001002    1088   3012   3024    511     7     3    0      0   L
</span>04930000 00001002    3136    940    940    153     9     2    0     8d   L
04ce0000 00001002      64     16     16      0     0     1    0      0   L
04cf0000 00001002    1088    192    192      6     2     1    0      0   L
05850000 00001002      64     28     28      1     1     1    0      0   L
05de0000 00001002      64     12     12      3     1     1    0      0   L
<span style="BACKGROUND-COLOR: #ff6666">比较第一次和第二次,发现在0x04920000上的内存有明显的增长
</span><span style="BACKGROUND-COLOR: #ff99ff">执行!heap -stat -h 04920000 去观察这段内存的详细情况
</span>0:025> !heap -stat -h 04920000
heap @ 04920000
group-by: TOTSIZE max-display: 20
size     #blocks     total     ( %) (percent of total busy bytes)
4 21a29 - 82cd0 (94.77)
d0 2a - 2220 (1.06)
20 cd - 19a0 (0.79)
90 2d - 1950 (0.78)
be0 2 - 17c0 (0.74)
e0 1b - 17a0 (0.73)
f0 19 - 1770 (0.73)
1f0 b - 1550 (0.66)
200 a - 1400 (0.62)
40 4f - 13c0 (0.61)
240 7 - fc0 (0.49)
bd0 1 - bd0 (0.37)
<span style="BACKGROUND-COLOR: #ff99ff">发现这段内存主要是由size=4的内存构成的</span>,而内存泄漏通常都是同一size的内存只分配,但没有释放引起的,所以,这个是值得高度怀疑的。
<span style="BACKGROUND-COLOR: #ff99ff">执行!heap -flt s 4 去查进程中size=4的所有内存</span>,
_HEAP @ 04920000
03659ab8 0002 0002 [01]   03659ac0    00004 - (busy)
03659ac8 0003 0002 [01]   03659ad0    00004 - (busy)
0365e8e8 0002 0003 [01]   0365e8f0    00004 - (busy)
0f2b9fe8 0003 0002 [11]   0f2b9ff0    00004 - (busy)
0f2d9760 0003 0003 [01]   0f2d9768    00004 - (busy)
0f2dcc20 0002 0003 [01]   0f2dcc28    00004 - (busy)
0f2dcc50 0002 0002 [01]   0f2dcc58    00004 - (busy)
0f2dd790 0002 0002 [01]   0f2dd798    00004 - (busy)
0f2dd7c0 0002 0002 [01]   0f2dd7c8    00004 - (busy)
0f2de260 0002 0002 [01]   0f2de268    00004 - (busy)
0f2de290 0002 0002 [01]   0f2de298    00004 - (busy)
0f2de2a0 0003 0002 [01]   0f2de2a8    00004 - (busy)
0f2df740 0002 0003 [01]   0f2df748    00004 - (busy)
0f2e0270 0002 0002 [01]   0f2e0278    00004 - (busy)
0f2e02a0 0002 0002 [01]   0f2e02a8    00004 - (busy)
0f2e02e0 0003 0002 [01]   0f2e02e8    00004 - (busy)
0f2e1270 0002 0003 [01]   0f2e1278    00004 - (busy)
0f2e1ce0 0002 0002 [01]   0f2e1ce8    00004 - (busy)
0f2e1d10 0002 0002 [01]   0f2e1d18    00004 - (busy)
0f2e27d0 0002 0002 [01]   0f2e27d8    00004 - (busy)
0f2e2800 0002 0002 [01]   0f2e2808    00004 - (busy)
0f2e2cc0 0002 0002 [01]   0f2e2cc8    00004 - (busy)
0f2e2cf0 0002 0002 [01]   0f2e2cf8    00004 - (busy)
0f2e3340 0003 0002 [01]   0f2e3348    00004 - (busy)
0f2e3d20 0002 0003 [01]   0f2e3d28    00004 - (busy)
0f2e4890 0002 0002 [01]   0f2e4898    00004 - (busy)
0f2e48c0 0003 0002 [01]   0f2e48c8    00004 - (busy)
<span style="BACKGROUND-COLOR: #ff99ff">然后执行!heap -p -a 0365e8f0 该内存分配时的堆栈。 这样就可以定位到内存泄露的根源了。</span>

结论:场景二比较试用于大部分情况,不需要是Debug版本,在现场调试,也不需要等待进程结束。

使用Windbg定位内存泄露相关推荐

  1. umdh windbg分析内存泄露

    A.利用工具umdh(user-mode dump heap)分析 1设置gflags.exe标志 r Gflags标志设置好后,开启cmd 键入要定位内存泄露的程序gflags.exe /i mem ...

  2. 如何使用Eclipse内存分析工具定位内存泄露

    本文以我司生产环境Java应用内存泄露为案例进行分析,讲解如何使用Eclipse的MAT分析定位问题 一. 背景 11月10号晚上8点收到报警邮件,一看是OOM 打开公司监控系统查看应用各项指标发现J ...

  3. 一种定位内存泄露的方法(Linux)

    2019独角兽企业重金招聘Python工程师标准>>> 目的: 本文是<一种定位内存泄露的方法(Solaris)>对应的Linux版本,调试器使用gdb.主要介绍实例部分 ...

  4. github snap android,GitHub - albuer/heapsnap: HeapSnap 是一个定位内存泄露的工具,适用于Android平台。...

    HeapSnap 1.HeapSnap 是什么 HeapSnap 是一个定位内存泄露的工具,适用于Android平台. 主要特性如下: 对系统负载低 不需要修改目标进程的源代码 支持Andoroid上 ...

  5. 利用linux的mtrace命令定位内存泄露(Memory Leak)

    一谈到内存泄露, 多数程序员都闻之色变. 没错, 内存泄露很容易引入, 但很难定位.  以你我的手机为例(假设不经常关机), 如果每天泄露一些内存, 那么开始的一个星期, 你会发现手机好好的, 当内存 ...

  6. Android Studio 选项菜单和动画结合_Android性能测试③-发现和定位内存泄露amp;卡顿...

    Android性能测试③-发现和定位内存泄露&卡顿 Android用户也许会经常碰到以下的问题: 1)应用后台开着,手机很快没电了--应用耗电大: 2)首次/非首次启动应用,进入应用特别慢-- ...

  7. Linux快速定位内存泄露和内存越界

    在日常开发中,遇到段错误是很常见的事,其中一种情况 Out of memory(OOM),内存泄露问题一般不好查找,但是可以借助工具来快速定位. 这里介绍的工具是valgrind,这个工具在build ...

  8. heapdump定位内存泄露

    工具下载hihttps://download.csdn.net/download/momo459548255/12832315 Linux下分析一个core内存泄露的过程(3s大法) 对于dump很大 ...

  9. 使用windbg定位内存问题【入门级】

    1. 背景 在开发过程中,我们可能遇到应用程序线程占用过大的问题,可以通过windbg命令去定位哪些类型,哪些内存一直占用堆资源,从而查出问题,解决问题. 2. 准备工作 工具: 抓取DUMP文件的工 ...

最新文章

  1. 电子表单系列谈之表单数据处理
  2. 46.一个例子了解C++中异常处理
  3. 重写GridView的Intellisence问题
  4. matlab基本运算与函数
  5. 【数据结构与算法】中缀表达式 - 后缀表达式 - 求值
  6. win10远程桌面连接ubuntu18.04
  7. Android开发之修改ImageView(图片)的颜色
  8. Java字节码反编译工具
  9. java获取spring注解的实体_Spring 注解实体类中非数据库字段属性
  10. spring boot 实现发送邮箱验证码
  11. 曲师大教务系统服务器,曲阜师范大学教务处系统入口地址
  12. Sublime Text关闭自动更新
  13. 如何为Mac视频添加模糊效果?
  14. 精灵骑士二觉_守护者二觉转职分析 精灵骑士二觉能有多强
  15. 大年三十整理的asp.net资料!(不得不收藏)
  16. Endnote如何添加CAJ格式文件
  17. java学籍管理系统部分代码_java学籍管理系统源代码
  18. js前端double无法显示,long精度丢失,layUI数据表格
  19. 1033 旧键盘打字 (20分)
  20. CSS控制背景颜色和背景图像的方法

热门文章

  1. 国信蓝点杯C语言高职高专组考试题目--记不太清了,大致就这些题目
  2. 网众无盘io服务器超时,网众无盘注意问题的解决教程
  3. 虚拟化之——内存虚拟化
  4. IIS服务器(Windows)远程修改ftp密码方法
  5. centOS安装python3.7
  6. 强者都在示弱,弱者都在逞强!
  7. sqlserver数据驱动bao1_在Jcreator下java联接SQL2008失败,数据库可以用telnet 127.0.0.1 1433登陆,数据库也可以用localhost登陆...
  8. window对象的方法
  9. 20170204老男孩用过的一些运维软件
  10. 数据挖掘软件SPSS Clementine 12安装教程