內存泄漏的分析

一.問題描述

當一個進程的內存異常大時,可能發生了內存泄漏,也多是內存中相關隊列等數據結構長度未做限制。數據結構

二.解決思路

若是問題很容易出現,最好是使用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

相關文章
相關標籤/搜索