• 【转】在 Windbg 下查找资源泄漏


    参考:http://hi.baidu.com/xingxing/item/f834ffeae93fcf2d5b7cfb9a

     

    有一个程序运行了一段时间后,内存占用呈线性增长,而且一直不降下来。

    在 windbg 中对其动态调试,以确定原因。

    先查看初始的堆状态:

    0:007> !heap -s

    NtGlobalFlag enables following debugging aids for new heaps:

        stack back traces

    LFH Key                   : 0x34d21697

    Termination on corruption : DISABLED

      Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 

                        (k)     (k)    (k)     (k) length      blocks cont. heap 

    -----------------------------------------------------------------------------

    00230000 08000002    1024    544   1024     17    14     1    0      0   LFH

    00010000 08008000      64      4     64      2     1     1    0      0      

    01a30000 08001002    1088     80   1088      4     3     2    0      0   LFH

    02d10000 08001002    1088    932   1088     98    38     2    0      0   LFH

    02ca0000 08001002     256     60    256      1     4     1    0      0   LFH

    02f10000 08001002     256    172    256    125     3     1    0      0      

    04340000 08001002      64      4     64      2     1     1    0      0      

    02e60000 08001002      64      4     64      2     1     1    0      0      

    044c0000 08011002     256      4    256      1     2     1    0      0      

    04690000 08001002     256      4    256      1     2     1    0      0      

    -----------------------------------------------------------------------------

    0:007> g

    (504.c9c): Break instruction exception - code 80000003 (first chance)

    eax=7ffd7000 ebx=00000000 ecx=00000000 edx=7709f125 esi=00000000 edi=00000000

    eip=770340f0 esp=0317ff5c ebp=0317ff88 iopl=0         nv up ei pl zr na pe nc

    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

    ntdll!DbgBreakPoint:

    770340f0 cc              int     3

    运行了一小段时间后,再看一下,和之前的对比,发现某个堆增长明显:

    0:007> !heap -s

    NtGlobalFlag enables following debugging aids for new heaps:

        stack back traces

    LFH Key                   : 0x34d21697

    Termination on corruption : DISABLED

      Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 

                        (k)     (k)    (k)     (k) length      blocks cont. heap 

    -----------------------------------------------------------------------------

    00230000 08000002    2048   1868   2048     17    17     2    0      0   LFH

    00010000 08008000      64      4     64      2     1     1    0      0      

    01a30000 08001002    1088     80   1088      4     3     2    0      0   LFH

    02d10000 08001002    1088    980   1088    147    40     2    0      0   LFH

    02ca0000 08001002     256     60    256      1     4     1    0      0   LFH

    02f10000 08001002     256    172    256    125     3     1    0      0      

    04340000 08001002      64      4     64      2     1     1    0      0      

    02e60000 08001002      64      4     64      2     1     1    0      0      

    044c0000 08011002     256      4    256      1     2     1    0      0      

    04690000 08001002     256      4    256      1     2     1    0      0      

    -----------------------------------------------------------------------------

    统计一下这个堆里的内存分配情况,发现 1000 字节的内存分配占了 86.97%,目标就锁定它了。

    0:007> !heap -stat -h 00230000

     heap @ 00230000

    group-by: TOTSIZE max-display: 20

        size     #blocks     total     ( %) (percent of total busy bytes)

       1000 158 - 158000  (86.97)

        494 16 - 64b8  (1.59)

        20 2fd - 5fa0  (1.51)

        34 161 - 47b4  (1.13)

        3980 1 - 3980  (0.91)

        d0 30 - 2700  (0.62)

        1034 2 - 2068  (0.51)

        78 39 - 1ab8  (0.42)

        c88 2 - 1910  (0.40)

        10 131 - 1310  (0.30)

        11f8 1 - 11f8  (0.28)

        208 7 - e38  (0.22)

        248 6 - db0  (0.22)

        58 23 - c08  (0.19)

        400 3 - c00  (0.19)

        80 15 - a80  (0.17)

        a28 1 - a28  (0.16)

        960 1 - 960  (0.15)

        928 1 - 928  (0.14)

        22 39 - 792  (0.12)

    看一下都是哪些堆申请的:

    0:007> !heap -flt s 1000

        _HEAP @ 230000

          HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state

            0027b810 0203 0000  [00]   0027b828    01000 - (busy)

            0027c900 0203 0203  [00]   0027c918    01000 - (busy)

            00285670 0203 0203  [00]   00285688    01000 - (busy)

            00286688 0203 0203  [00]   002866a0    01000 - (busy)

            002876a0 0203 0203  [00]   002876b8    01000 - (busy)

            002886b8 0203 0203  [00]   002886d0    01000 - (busy)

            002896d0 0203 0203  [00]   002896e8    01000 - (busy)

            0028a6e8 0203 0203  [00]   0028a700    01000 - (busy)

            0028bf10 0203 0203  [00]   0028bf28    01000 - (busy)

            0028cf28 0203 0203  [00]   0028cf40    01000 - (busy)

            0028df40 0203 0203  [00]   0028df58    01000 - (busy)

    ....

    ....

    ....

        _HEAP @ 10000

        _HEAP @ 1a30000

        _HEAP @ 2d10000

        _HEAP @ 2ca0000

        _HEAP @ 2f10000

        _HEAP @ 4340000

        _HEAP @ 2e60000

        _HEAP @ 44c0000

        _HEAP @ 4690000

    随便挑几个地址看一下调用栈:

    0:007> !heap -p -a 0303aec0

        address 0303aec0 found in

        _HEAP @ 230000

          HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state

            0303aec0 0221 0000  [00]   0303aed8    01000 - (busy)

            7707dd6c ntdll!RtlAllocateHeap+0x00000274

            7541f947 KERNELBASE!FindNextFileW+0x00000090

            ...

            ...

            771a3c45 kernel32!BaseThreadInitThunk+0x0000000e

            770637f5 ntdll!__RtlUserThreadStart+0x00000070

            770637c8 ntdll!_RtlUserThreadStart+0x0000001b

     再结合源代码,确定是 FindNextFileW 遍历文件完成之后,没有调用 FindClose 关闭句柄,导致资源没有被释放。

     在使用上面的方法调试之前,要先打开 Create user mode stack trace database

    0:004> !gflag +ust

    Current NtGlobalFlag contents: 0x00001000

        ust - Create user mode stack trace database

  • 相关阅读:
    asp.net mvc ActionResult
    理解RESTful架构
    Entity Framework Code First Migrations--EF 的数据迁移
    java多态的理解
    webuploader上传文件,图片
    java文档注释--javadoc的用法
    微信小程序初窥-环境搭建
    学神:我天天玩没怎么学。但是你怎么成了学神?
    c#中的弱引用:WeakReference
    Cron表达式简单的介绍
  • 原文地址:https://www.cnblogs.com/daxingxing/p/2535089.html
Copyright © 2020-2023  润新知