一般我用兩種方法:
1. 用Debug Diagnostic Tool的Leak監測分析功能,注意配置好PDB文件。
???DebugDiag 會生成完整的Leak Report。看看幫助很方便。
2. 用WinDBG的!heap擴展命令。注意要為你的程序打開Normal PageHeap。
???然后當內存出現明顯泄漏時用 !heap -l 命令分析內存。-l 參數使用類似Java/C#的Garbage Collection算法,這樣能找到大部分在程序中沒有被引用的HeapBlock。
???這是一個示例輸出:
0:011> !heap -l Searching the memory for potential unreachable busy blocks. ...... Heap 017a0000 Scanning VM ... Scanning references from 3586 busy blocks (0 MBytes) ... Entry???????????User?????????Heap??????????? Segment????????Size? PrevSize? Unused??? Flags ----------------------------------------------------------------------------- 00253198? 002531a0? 00250000? 00250000??????? b8??????? 78??????? 14? busy extra 00253250? 00253258? 00250000? 00250000??????? 78??????? b8??????? 13? busy extra 00286a38? 00286a40? 00250000? 00250000??????? b8??????? b8??????? 15? busy extra 00286af0? 00286af8? 00250000? 00250000??????? b8??????? b8??????? 15? busy extra 00286ba8? 00286bb0? 00250000? 00250000??????? b8??????? b8??????? 15? busy extra 00286c60? 00286c68? 00250000? 00250000??????? b8??????? b8??????? 15? busy extra 00286d18? 00286d20? 00250000? 00250000??????? b8??????? b8??????? 15? busy extra 00286dd0? 00286dd8? 00250000? 00250000??????? b8??????? b8??????? 15? busy extra
???找到最常出現的Size值(這里是b8),一般就是持續泄漏的內存塊大小。隨便選一行,記下Entry地址(比如00286a3)。
???dt _DPH_BLOCK_INFORMATION 00286a3 + 8???//8 是HeapEntry結構的大小,跟在其后的就是PageHeap meta data,結構名是_DPH_BLOCK_INFORMATION.
???0:011> dt _DPH_BLOCK_INFORMATION 00286a3 + 8 ntdll!_DPH_BLOCK_INFORMATION ?? +0x000 StartStamp?????? : 0xabcdaaaa ?? +0x004 Heap???????????? : 0x80151000 ?? +0x008 RequestedSize??? : 0x7b ?? +0x00c ActualSize?????? : 0xa3 ?? +0x010 FreeQueue??????? : _LIST_ENTRY [ 0x2e - 0x0 ] ?? +0x010 TraceIndex?????? : 0x2e ?? +0x018 StackTrace?????? : 0x00357140 ?? +0x01c EndStamp???????? : 0xdcbaaaaa
???看到StackTrace那行,這是相應的user mode stack trace database的地址。
0:011> dds 0x00357140 00357140? abcdaaaa ...... 00357160? 7c949d18 ntdll!RtlAllocateHeapSlowly+0x44 00357164? 7c91b298 ntdll!RtlAllocateHeap+0xe64 00357168? 004017fe 06_DebugDiag_MemoryLeak!MyHeapAlloc+0x1e [g:\debugging101\projects\06_debugdiag_memoryleak\06_debugdiag_memoryleak\06_debugdiag_memoryleak.cpp @ 11] 0035716c? 0040182b 06_DebugDiag_MemoryLeak!WorkerThread+0x1b [g:\debugging101\projects\06_debugdiag_memoryleak\06_debugdiag_memoryleak\06_debugdiag_memoryleak.cpp @ 27] 00357170? 7c80b683 kernel32!BaseThreadStart+0x37
???這就是上次通過Heap Manager函數操作這個HeapBlock的StackTrace,一般也就是分配這個Block的地方。
???希望可以幫到你。
鴻鵠安知燕雀之志 |