c++ - 默认 Win32 项目具有恒定数量的内存泄漏

标签 c++ winapi memory-leaks gdi

简介及相关资料:

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

我使用 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 上也会出现同样的效果。

问题:

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

谢谢你。

最好的祝福。

最佳答案

就实际泄漏而言,这并不是真正值得担心的事情,因为它可能不是(即误报)。真正的问题是,这会影响您诊断自己的内存泄漏的能力,因为它们可能会因这些误报而“丢失”。

Why is this happening?



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

how to eliminate these small memory leaks?



您无法真正消除这些泄漏,特别是如果您真的与它们没有任何关系(即,它们来自 GUI 库堆栈,而不是来自您的应用程序)。您可以做的最好的事情是将这些诊断报告给负责支持和维护这些库的人(例如 Microsoft),但它可能会被忽略或被视为正常发生(不是真正的泄漏)。

现在,对于真正的问题,如果您想诊断自己潜在的内存泄漏,那么您将必须找到一种系统的方法来规避或忽略来自 GUI 库堆栈的“泄漏”。以下是一些典型的解决方案:
  • 经常检查泄漏并避免做会增加误报数量的事情(例如,调整大小)。学会“了解您的泄漏”,通过经常检查,您将熟悉来自 GUI 库堆栈的泄漏,并且能够忽略它们或从诊断中“减去”它们,只看到真实的泄漏。
  • 使用过滤工具过滤内存诊断工具的输出。大多数检查泄漏的工具都有过滤选项来过滤(或静音)来自某些库或函数的警告或错误。您可以使用它们来消除在这些第三方库中检测到的虚假泄漏。但注意不要过滤太多(例如,过滤掉来自 CRT 的所有泄漏),您应该保持保守(您甚至可以在代码中引入故意的内存泄漏以检查它们是否被过滤掉)。
  • 模块化您的应用程序,以便大多数重要代码(繁重的代码)可以在更简单的命令行程序中运行。换句话说,把 GUI 变成一个简单的前端(这很容易做到无泄漏),它使用一些繁重的后端代码。您可以将该后端代码移植到更简单的命令行程序中,从而完全避免 GUI 库堆栈,并允许您更有效地检查内存泄漏,而不会产生所有“污染”。这是任何严肃项目的推荐解决方案,它还促进了良好的编码实践(单元测试、模块化代码、最小的相互依赖性等)。
  • 关于c++ - 默认 Win32 项目具有恒定数量的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20664677/

    相关文章:

    c++ - 覆盖使用 new 关键字初始化的变量 c++

    c++ - AVL Delete 方法行为奇怪,C++

    c++ - 复制文件时如何调用取消? (使用复制文件ex函数配合复制进度例程回调函数)

    javascript - Javascript 是否会删除已删除 DOM 元素的事件处理程序?

    javascript - 在 Chrome 中分析 Javascript 时,我怎么知道我已经处理了内存泄漏?

    c++ - 32/64 位 Windows/Linux 应用程序

    c++ - 设计模式的重要性?

    winapi - 更改使用资源文件的VB6项目的exe图标

    windows - CreateProcess 执行 Windows 命令

    c++ - 在 Visual Studio 中,与 std::async 一起使用时未调用 `thread_local` 变量的析构函数,这是错误吗?