zoukankan      html  css  js  c++  java
  • Windows调试——使用windbg查找内存泄露

    内存泄露查找方法

    C++程序员经常不注意内存使用的关闭,虽然此类问题不会导致程序逻辑问题,但随着时间的推移,内存占用量越来越多,最终导致程序崩掉。对服务端的程序,内存泄漏经常是致命的。 
    对于已经存在内存泄露的程序,可能Windbg查找内存泄露的代码。下面介绍如果通过Windbg查找内存泄露。

    1. Windbg 加载程序依赖库所用pdb文件。
    2. 挂载进程或者加载已生成的pdb文件
    3. 输入命令查看内存。

    3.1 !heap –s 查看程序内存状况 
    0:000> !heap -s 
    NtGlobalFlag enables following debugging aids for new heaps: 
    stack back traces 
    LFH Key : 0x73ccd2bf 
    Termination on corruption : DISABLED 
    Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast

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

    004e0000 08000002 4096 3968 4096 45 86 3 0 0 LFH 
    006f0000 08001002 1088 804 1088 40 3 2 0 0 LFH 
    002d0000 08001002 1280 292 1280 9 16 2 0 0 LFH 
    Virtual block: 05f10000 - 05f10000 (size 00000000) 
    Virtual block: 45fd0000 - 45fd0000 (size 00000000) 
    Virtual block: 466d0000 - 466d0000 (size 00000000) 
    Virtual block: 47310000 - 47310000 (size 00000000) 
    00b70000 08001002 250748 250044 250748 3122 925 58 4 9 LFH 
    00480000 08001002 256 148 256 6 1 1 0 0 LFH 
    04f80000 08001002 256 4 256 2 1 1 0 0 
    00bb0000 08011002 256 80 256 74 3 1 0 0 
    04ed0000 08001002 64 16 64 13 1 1 0 0 
    059e0000 08001002 64 4 64 2 1 1 0 0 
    05bd0000 08001002 64 4 64 2 1 1 0 0 
    05dc0000 08001002 256 4 256 1 2 1 0 0 
    04e40000 08001002 1280 300 1280 49 12 2 0 0 LFH 
    Virtual block: 6b310000 - 6b310000 (size 00000000) 
    Virtual block: 6b520000 - 6b520000 (size 00000000) 
    180f0000 08001002 1088 676 1088 267 5 2 2 23 
    18740000 08001002 7232 6236 7232 3956 49 13 0 26 LFH 
    External fragmentation 63 % (49 free blocks) 
    18b60000 08001002 1088 220 1088 24 8 2 0 0 LFH 
    04e30000 08001002 1088 148 1088 2 4 2 0 0 LFH

    过一段时间再次通过!heap –s 查看程序内存状况。找出增长较快的内存块,如00b70000。

    3.2 !heap -stat –h 查看00b70000内存详细情况 
    0:000> !heap -stat -h 00b70000 
    heap @ 00b70000 
    group-by: TOTSIZE max-display: 20 
    size #blocks total ( %) (percent of total busy bytes) 
    ea60 f88 - e382300 (57.83) 
    9c61334 1 - 9c61334 (39.75) 
    1b7730 1 - 1b7730 (0.44) 
    147254 1 - 147254 (0.32) 
    124f74 1 - 124f74 (0.29) 
    c de5e - a6c68 (0.17) 
    2000 41 - 82000 (0.13) 
    214 3d1 - 7ee54 (0.13) 
    28 2a67 - 6a018 (0.11) 
    42b0 14 - 535c0 (0.08) 
    1c 2914 - 47e30 (0.07) 
    2b70 14 - 364c0 (0.05) 
    14 29b4 - 34210 (0.05) 
    32000 1 - 32000 (0.05) 
    18 1ac1 - 28218 (0.04) 
    4 7df4 - 1f7d0 (0.03) 
    1d4c4 1 - 1d4c4 (0.03) 
    1740 14 - 1d100 (0.03) 
    2408 c - 1b060 (0.03) 
    208 cc - 19e60 (0.03)

    3.3 !heap -flt s 查进程中size=ea60的所有内存 
    0:000> !heap -flt s ea60 
    _HEAP @ 4e0000 
    _HEAP @ 6f0000 
    _HEAP @ 2d0000 
    _HEAP @ b70000 
    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 
    5272cc18 1d4f 0000 [00] 5272cc30 0ea60 - (busy) 
    537bc578 1d4f 1d4f [00] 537bc590 0ea60 - (busy) 
    537cbf98 1d4f 1d4f [00] 537cbfb0 0ea60 - (busy) 
    53862f20 1d4f 1d4f [00] 53862f38 0ea60 - (busy) 
    53871998 1d4f 1d4f [00] 538719b0 0ea60 - (busy) 
    53890608 1d4f 1d4f [00] 53890620 0ea60 - (busy) 
    538ace68 1d4f 1d4f [00] 538ace80 0ea60 - (busy) 
    538bb8e0 1d4f 1d4f [00] 538bb8f8 0ea60 - (busy) 
    538dcec8 1d4f 1d4f [00] 538dcee0 0ea60 - (busy) 
    53901af8 1d4f 1d4f [00] 53901b10 0ea60 - (busy) 
    53910570 1d4f 1d4f [00] 53910588 0ea60 - (busy) 
    5391efe8 1d4f 1d4f [00] 5391f000 0ea60 - (busy) 
    539b71a0 1d4f 1d4f [00] 539b71b8 0ea60 - (busy) 
    539c5c18 1d4f 1d4f [00] 539c5c30 0ea60 - (busy) 
    539d4690 1d4f 1d4f [00] 539d46a8 0ea60 - (busy) 
    539e3108 1d4f 1d4f [00] 539e3120 0ea60 - (busy) 
    539f1b80 1d4f 1d4f [00] 539f1b98 0ea60 - (busy) 
    53a005f8 1d4f 1d4f [00] 53a00610 0ea60 - (busy) 
    53a0f070 1d4f 1d4f [00] 53a0f088 0ea60 - (busy) 
    53a20f98 1d4f 1d4f [00] 53a20fb0 0ea60 - (busy) 
    53a2fa10 1d4f 1d4f [00] 53a2fa28 0ea60 - (busy) 
    53a4e6b8 1d4f 1d4f [00] 53a4e6d0 0ea60 - (busy) 
    53a66fa0 1d4f 1d4f [00] 53a66fb8 0ea60 - (busy) 
    53a75a18 1d4f 1d4f [00] 53a75a30 0ea60 - (busy) 
    71614e20 1d4f 1d4f [00] 71614e38 0ea60 - (busy) 
    71623898 1d4f 1d4f [00] 716238b0 0ea60 - (busy) 
    71632310 1d4f 1d4f [00] 71632328 0ea60 - (busy) 
    …………………………….. 
    3.4 !heap -p –a 查看内存堆栈,定位泄露根源。 
    0:000> !heap -p -a 71614e38 
    address 71614e38 found in 
    _HEAP @ b70000 
    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 
    71614e20 1d4f 0000 [00] 71614e38 0ea60 - (busy) 
    Trace: 5be4158 
    76f5dfa2 ntdll!RtlAllocateHeap+0x00000274 
    72873db8 MSVCR90!malloc+0x00000079 
    70e7b9dd BInterface!osip_malloc+0x0000000d 
    70e83f93 BInterface!sdp_message_to_str+0x00000073 
    70e3751f BInterface!CSdpParse::sdp_to_str+0x0000001f 
    70e14b06 BInterface!CUserAgent::DoStartStream+0x00000316 
    70e26e3b BInterface!BI_StartRealStream+0x000000fb

    0:000> !heap -p -a 721acf68 
    address 721acf68 found in 
    _HEAP @ b70000 
    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 
    721acf50 1d4f 0000 [00] 721acf68 0ea60 - (busy) 
    Trace: 5be4158 
    76f5dfa2 ntdll!RtlAllocateHeap+0x00000274 
    72873db8 MSVCR90!malloc+0x00000079 
    70e7b9dd BInterface!osip_malloc+0x0000000d 
    70e83f93 BInterface!sdp_message_to_str+0x00000073 
    70e3751f BInterface!CSdpParse::sdp_to_str+0x0000001f 
    70e14b06 BInterface!CUserAgent::DoStartStream+0x00000316 
    70e26e3b BInterface!BI_StartRealStream+0x000000fb

      1. 通过以上分析可以定位到BInterface相关接口导致内存泄露。
  • 相关阅读:
    一个好的技术管理人员需要知道的几件事
    团队必经的五个阶段以及好团队的七个特征
    作为CTO如何做技术升级
    技术领导画像
    TF-IDF原理
    KNN和K-Means的区别
    图数据库入门
    Hbase和Hive的异同
    谈谈机器学习面试
    关于领导力的理解
  • 原文地址:https://www.cnblogs.com/lidabo/p/14363168.html
Copyright © 2011-2022 走看看