當一個進程的內存異常大時,可能發生了內存泄漏,也多是內存中相關隊列等數據結構長度未做限制。數據結構
若是問題很容易出現,最好是使用umdh工具來進行判斷,此工具的使用方法在其幫助手冊中有詳細介紹,此處再也不贅述。
本文中說的是另一處思路。衆所周知,進程中分爲代碼空間,數據空間,棧,堆等。除了堆以外,其餘部分都是基本固定和有上限限制的。堆的空間大小對於64位的進程能夠說基本不受限的,所以咱們的思路是查看堆中的內容。工具
使用windbg attach到進程後,依次執行spa
0:003> !heap -s NtGlobalFlag enables following debugging aids for new heaps: stack back traces LFH Key : 0x0000008f4b2ee335 Termination on corruption : ENABLED Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap ------------------------------------------------------------------------------------- 0000000002460000 08000002 1024 432 1024 1 6 1 0 0 LFH 0000000000010000 08008000 64 8 64 5 1 1 0 0 0000000000020000 08008000 64 64 64 61 1 1 0 0 00000000001a0000 08001002 1088 256 1088 3 1 2 0 0 LFH 00000000040a0000 08001002 512 28 512 0 2 1 0 0 0000000004080000 08001002 1088 332 1088 6 5 2 0 0 LFH ------------------------------------------------------------------------------------- 0:003> !heap -stat -h 0000000004080000 heap @ 0000000004080000 group-by: TOTSIZE max-display: 20 size #blocks total ( %) (percent of total busy bytes) 6608 1 - 6608 (36.24) 4000 1 - 4000 (22.73) 1000 2 - 2000 (11.37) 1001 1 - 1001 (5.68) b00 1 - b00 (3.91) 2c8 3 - 858 (2.96) 200 4 - 800 (2.84) 401 1 - 401 (1.42) 3ff 1 - 3ff (1.42) 30a 1 - 30a (1.08) 178 2 - 2f0 (1.04) 28 11 - 2a8 (0.94) 38 a - 230 (0.78) 220 1 - 220 (0.75) 100 2 - 200 (0.71) 58 5 - 1b8 (0.61) 160 1 - 160 (0.49) 130 1 - 130 (0.42) 30 6 - 120 (0.40) 48 3 - d8 (0.30) 0:003> !heap -flt s 401(這個是隨機抽選的,固然我寫的示例中正好是泄漏了這麼大) _HEAP @ 2460000 _HEAP @ 10000 _HEAP @ 20000 _HEAP @ 1a0000 _HEAP @ 40a0000 _HEAP @ 4080000 HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 0000000003f907e0 0043 0000 [00] 0000000003f90810 00401 - (busy) 0:003> !heap -p -a 0000000003f90810 address 0000000003f90810 found in _HEAP @ 4080000 HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 0000000003f907e0 0043 0000 [00] 0000000003f90810 00401 - (busy) 7700cc0d ntdll! ?? ::FNODOBFM::`string'+0x000000000001913b 71048d17 MSVCR100!malloc+0x000000000000005b 71048ddb MSVCR100!operator new+0x000000000000001f 13fa423d7 test!test1+0x0000000000000017 13fa47ed4 test!boost::detail::thread_data<long (__cdecl*)(void)>::run+0x0000000000000014 13fa52e43 test!boost::`anonymous namespace'::thread_start_function+0x0000000000000043 71001d9f MSVCR100!_callthreadstartex+0x0000000000000017 71001e3b MSVCR100!_threadstartex+0x000000000000007f 76e6652d kernel32!BaseThreadInitThunk+0x000000000000000d 76f9c521 ntdll!RtlUserThreadStart+0x000000000000001d
這樣就能夠定位到申請內存的代碼行數(須要注意的是,設置符號文件,而且執行 gflags.exe /i *.exe +ust)debug
1.有時候咱們可能沒有來得及設置gflags,這時能夠查看堆中的內存內容來猜想可能泄漏的地方。
2.heap -s能夠執行屢次,觀測內存增長的堆地址進行分析。3d