DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

内存泄露查找方法

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相关接口导致内存泄露。
posted on 2021-02-02 17:19  DoubleLi  阅读(642)  评论(0编辑  收藏  举报