内存泄漏。堆积增长,但分配不是 [英] Memory leak. Heap growing, but allocations not

查看:64
本文介绍了内存泄漏。堆积增长,但分配不是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个用C ++编写的具有内存泄漏的Windows程序。我们收集了几个垃圾箱,以确定泄漏的位置。我这样做的标准方法是在两个转储上使用!heap -s 来使用WinDbg来找出正在增长的堆,然后使用!heap -stat -h

< /地址> 的。问题是,虽然我可以看到特定的堆增长,但是当我运行时,没有任何分配在增长!heap -stat -h。从历史上看,这种方法帮助我找到了我的记忆泄漏的地方,但现在它似乎让我失望了。我在哪里可以离开这里?



我尝试过:



这是第一次转储转储文件的输出:

We have a windows program that was written in C++ that has a memory leak. We collected a couple of dumps in order to determine where the leak is. My standard method of doing this is to use WinDbg using the !heap -s on the two dumps to find out which heap is growing, then use !heap -stat -h

. The problem is that while I can see a specific heap growing, none of the allocations are growing when I run !heap -stat -h. Historically, this methodology has helped me find out where my memory is leaking, but now it seems to have failed me.Where do I go from here?

What I have tried:

Here is the output of the dump file from the first dump:

0:000> !heap -s


************************************************************************************************************************
                                              NT HEAP STATS BELOW
************************************************************************************************************************
LFH Key                   : 0x7230554a
Termination on corruption : DISABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
005b0000 00000002    8284   5896   8176    137   148     5    6      b   LFH
00830000 00001002    1188    204   1080     27     8     2    0      0   LFH
02bd0000 00001002    1188    128   1080     24     6     2    0      0   LFH
02b90000 00041002      60      4     60      0     1     1    0      0      
03100000 00001002    1188    128   1080     22     6     2    0      0   LFH
05cc0000 00001003      60      8     60      6     1     1    0    N/A   
05dc0000 00001003    1080    124   1080     77    24     2    0    N/A   
05f10000 00001003      60      4     60      2     1     1    0    N/A   
05ef0000 00001003      60      4     60      2     1     1    0    N/A   
060b0000 00001003      60      4     60      2     1     1    0    N/A   
062a0000 00001003      60      4     60      2     1     1    0    N/A   
05d60000 00001003      60      4     60      2     1     1    0    N/A   
06080000 00001003      60      4     60      2     1     1    0    N/A   
05e70000 00001003      60      4     60      2     1     1    0    N/A   
064a0000 00001003      60      4     60      2     1     1    0    N/A   
05c90000 00001003      60      4     60      2     1     1    0    N/A   
05c50000 00001003      60      4     60      2     1     1    0    N/A   
-----------------------------------------------------------------------------



这是第二个文件的输出:


Here is the output of the second file:

0:000> !heap -s


************************************************************************************************************************
                                              NT HEAP STATS BELOW
************************************************************************************************************************
LFH Key                   : 0x7230554a
Termination on corruption : DISABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
005b0000 00000002   81224  68308  81116   1676   474     9    6     15   LFH
00830000 00001002    1188    260   1080     34     6     2    0      0   LFH
02bd0000 00001002    1188    148   1080     28     6     2    0      0   LFH
02b90000 00041002      60      4     60      0     1     1    0      0      
03100000 00001002    1188    148   1080     27     6     2    0      0   LFH
05cc0000 00001003      60      8     60      6     1     1    0    N/A   
05dc0000 00001003    1080    124   1080     62    57     2    0    N/A   
05f10000 00001003      60      4     60      2     1     1    0    N/A   
05ef0000 00001003      60      4     60      2     1     1    0    N/A   
060b0000 00001003      60      4     60      2     1     1    0    N/A   
062a0000 00001003      60      4     60      2     1     1    0    N/A   
05d60000 00001003      60      4     60      2     1     1    0    N/A   
06080000 00001003      60      4     60      2     1     1    0    N/A   
05e70000 00001003      60      4     60      2     1     1    0    N/A   
064a0000 00001003      60      4     60      2     1     1    0    N/A   
05c90000 00001003      60      4     60      2     1     1    0    N/A   
05c50000 00001003      60      4     60      2     1     1    0    N/A   
21430000 00001002    1188     80   1080     18     8     2    0      0   LFH
-----------------------------------------------------------------------------





正如你所看到的,005b0000的堆已经增长了很多。现在,当我使用!heap -stat -h 005b0000 时,第一个转储将返回以下内容:



As you can see, the heap at 005b0000 has grown quite a bit. Now, when I use !heap -stat -h 005b0000 the first dump returns the following:

0:000> !heap -stat -h 005b0000 
 heap @ 005b0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    27c9 25 - 5c00d  (24.26)
    2680 11 - 28e80  (10.78)
    17b0c 1 - 17b0c  (6.25)
    3bc 35 - c5ec  (3.26)
    c da5 - a3bc  (2.70)
    c4 ca - 9aa8  (2.55)
    a0 e4 - 8e80  (2.35)
    8000 1 - 8000  (2.11)
    30 27f - 77d0  (1.97)
    c80 9 - 7080  (1.85)
    24 2d7 - 663c  (1.68)
    1000 5 - 5000  (1.32)
    4e20 1 - 4e20  (1.29)
    4a20 1 - 4a20  (1.22)
    40 10d - 4340  (1.11)
    1048 4 - 4120  (1.07)
    208 20 - 4100  (1.07)
    4040 1 - 4040  (1.06)
    4000 1 - 4000  (1.05)
    2000 2 - 4000  (1.05)





这是来自第二个转储文件:



And this is from the second dump file:

0:000> !heap -stat -h 005b0000 
 heap @ 005b0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    27c9 25 - 5c00d  (23.73)
    2680 11 - 28e80  (10.55)
    17b0c 1 - 17b0c  (6.11)
    3bc 32 - bab8  (3.01)
    c e09 - a86c  (2.71)
    c4 ca - 9aa8  (2.49)
    a0 e6 - 8fc0  (2.32)
    8000 1 - 8000  (2.06)
    30 283 - 7890  (1.94)
    c80 9 - 7080  (1.81)
    24 2d8 - 6660  (1.65)
    40 153 - 54c0  (1.37)
    1000 5 - 5000  (1.29)
    4e20 1 - 4e20  (1.26)
    4a20 1 - 4a20  (1.19)
    1048 4 - 4120  (1.05)
    4040 1 - 4040  (1.04)
    4000 1 - 4000  (1.03)
    2000 2 - 4000  (1.03)
    208 1f - 3ef8  (1.02)

推荐答案

我会检查代码中有趣的代码路径内存已分配。将它们注释掉或在循环中运行它们。



我解决了这个工具的一些问题内存泄漏检测



有时内存分配是由像HeapAlloc这样的系统调用完成的,你找不到任何泄漏。



使用vld或其他工具总是一个好主意。对于deleaker是可用的试用版。 ; - )
I would inspect the code for interesting code pathes in which memory is allocated. Comments them out or run them in loops.

I solved some problems with this tools for Memory Leak Detection.

Sometimes memory allocation is done by system calls like HeapAlloc where you wont find any leaks.

Using the vld or another tools is always a good idea. For deleaker is a trial version available. ;-)


您应该学习尽快使用调试器。而不是猜测你的代码在做什么,现在是时候看到你的代码执行并确保它完成你期望的。



调试器允许你跟踪执行逐行检查变量,你会看到它有一个停止做你期望的点。

调试器 - 维基百科,免费的百科全书 [ ^ ]

掌握Visual Studio 2010中的调试 - A初学者指南 [ ^ ]



调试器在这里向您展示您的代码正在做什么,您的任务是与它应该做什么进行比较。 />
当代码不做ex的时候你接近一个bug。



使用调试器,检查你分配内存的位置以及释放它的位置。

内存泄漏是指你为一个变量分配一些内存并且永远不会释放这个内存。

你可能没有先释放内存而忘记内存。
You should learn to use the debugger as soon as possible. Rather than guessing what your code is doing, It is time to see your code executing and ensuring that it does what you expect.

The debugger allow you to follow the execution line by line, inspect variables and you will see that there is a point where it stop doing what you expect.
Debugger - Wikipedia, the free encyclopedia[^]
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]

The debugger is here to show you what your code is doing and your task is to compare with what it should do.
When the code don't do what is expected, you are close to a bug.

With the debugger, inspect where you allocate some memory and where you free it.
the memory leak is when you allocate some memory to a variable and never free this memory.
You probably loose track of the memory without freeing it first.


一个好的旧的代码审查也可能有所帮助,特别是如果你可以让其他人查看你的代码。

一双新眼睛有时可以在几分钟内检测到,你一直试图找到的问题几个小时。



在这种情况下,你可以专注于内存分配和内存释放。

寻找各种分配并确保你自由代码的所有路径中的内存。

如果代码执行辅助路径或发生异常,则很常见内存未被释放。

它是并不是闻所未闻的那个malloc被调用两次并且只释放一次,因为代码是用来编写的匆忙或后来加入是由另一个人制作的。



也许你已经这样做了,但如果没有,即使它很无聊也许值得一试要做的事。
A good old code review might help as well, especially if you can get someone else to look at your code.
A pair of fresh eyes can sometimes detect in minutes, the problems you have been trying to find for hours.

In this case you could focus on memory allocation and memory release only.
Look for all kinds of alloc and make sure you free the memory in all paths of the code.
It is very common to see that memory is not released if the code executes a secondary path or an exception occurs.
It is not unheard of that malloc is called twice and free only once, because the code was written in a hurry or a later addition was made by another person.

Maybe you have done this already, but if not it might be worth a try even if it is a boring thing to do.


这篇关于内存泄漏。堆积增长,但分配不是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆