简介和相关信息:

我从事的原始项目的内存泄漏较小,因此,我决定执行一个小型测试,以便检测可能导致它们的原因。

我已经使用Visual Studio向导创建了一个Win32项目。
我还没有添加任何,因为它是使用向导创建的,所以我刚刚添加了它。
我已经使用工具GDIView(http://www.nirsoft.net/utils/gdi_handles.html)查看是否存在任何固有的GDI leaks

问题:

每次我调整窗口大小时,此工具都会显示我的应用程序泄漏的+3个区域。

我为解决问题所做的努力:

由于该项目是由Visual Studio向导完成的,因此我尝试从头开始创建一个简单的项目,但是出现了相同的+3区域。

通读CodeProject上有关区域的一些文章,我偶然发现了一些演示应用程序的演示应用程序。

当我打开GDIView时,这些应用程序还会泄漏+3个区域。

当我打开Task Manager来查看是否确实发生了小内存泄漏时,所有这一切都得到了验证-这确实发生是因为内存略微增加了,之后保持不变,无论我调整窗口大小是多少次。

我使用Microsoft Visual Studio 2008 Express Edition,但是在常规Visual Studio 2008中也创建空项目时,也检测到该问题。

我在Windows XP上工作,但在Windows 7上也有相同的效果。

题:

为什么会发生这种情况,以及如何消除这些小的内存泄漏?

谢谢。

最好的祝福。

最佳答案

就实际泄漏而言,这并不是真正要担心的事情,因为它可能不是(即假阳性)。真正的问题是,这会损害您诊断自己的内存泄漏的能力,因为它们可能因这些假阳性而“丢失”。



这种“泄漏”很常见。我通常使用用于GUI应用程序的Qt + Linux(KDE),并且始终看到非常相似的“泄漏”。问题在于,在任何GUI软件中,您至少都会具有以下几层:应用程序,GUI库,OS“内核”库和图形驱动程序。以我的经验,大多数报告的“泄漏”都来自图形驱动程序,大概是因为这种低级代码需要大量“黑客”,而这些“黑客”可以被典型的内存诊断工具(如Valgrind(或您正在使用的任何内容)。对于OS内核代码也可以做出类似的论点,尽管根据我的经验,出现的“泄漏”要少得多(我认为他们可能在避免这些“黑客”方面付出了更多的努力)。在GUI库(Qt,Win32 API等)中,出于类似的原因,通常也存在类似的“泄漏”。当然,不排除在任何这些层中都可能存在实际泄漏,但是您必须在没有泄漏的前提下进行工作,并且内存消耗在一段时间后稳定下来的事实表明,可能是至少没有真正的泄漏,至少没有任何可能造成破坏的泄漏(例如失控的内存消耗)(顺便说一句,这种内存消耗先增加然后稳定的行为是完全正常的,这与堆碎片不断增长并最终达到平衡有关)。



您无法真正消除这些泄漏,尤其是如果您确实与它们没有任何关系(即,这些泄漏来自GUI库堆栈,而不是来自应用程序)。您所能做的最好的就是将诊断信息报告给负责这些库的支持和维护的人员(例如Microsoft),但很可能会忽略或认为它是正常现象(实际上不是泄漏)。

现在,对于真正的问题,如果您想诊断自己的潜在内存泄漏,那么您将必须找到一种系统的方法来规避或忽略来自GUI库堆栈的“泄漏”。以下是一些典型的解决方案:

  • 经常检查是否泄漏,并避免做会增加误报次数的事情(例如调整大小)。从某种意义上说,学会“了解泄漏”,即通过经常检查,您将熟悉从GUI库堆栈中泄漏出来的泄漏,并能够忽略它们或从诊断中“减去”它们,只看到真实的泄漏。泄漏。
  • 使用过滤工具来过滤内存诊断工具的输出。大多数检查泄漏的工具都将具有过滤选项,以过滤掉(或静音)某些库或函数发出的警告或错误。您可以使用它们来消除在这些第三方库中检测到的虚假泄漏。但请注意不要过滤得太多(例如,像过滤掉所有来自CRT的泄漏一样),您应该保持保守(您甚至可以在代码中引入故意的内存泄漏,以检查它们是否被过滤掉)。
  • 模块化您的应用程序,以便可以在更简单的命令行程序中运行大多数重要代码(繁重的代码)。换句话说,使GUI成为使用一些繁重的后端代码的简单前端(易于实现无泄漏)。您可以将该后端代码移植到一个更简单的命令行程序中,从而完全避免了GUI库堆栈,并且可以在没有所有“污染”的情况下更有效地检查内存泄漏。对于任何严肃的项目,这都是推荐的解决方案,它还会促进良好的编码实践(单元测试,模块化代码,最小的相互依赖关系等)。
  • 10-04 23:10
    查看更多