【问题标题】:Valgrind doesn't detect any memory leaks. How safe is that?Valgrind 没有检测到任何内存泄漏。那有多安全?
【发布时间】:2011-12-05 07:06:07
【问题描述】:

我已经通过valgrind 运行了我的代码,结果如下:

==4492== Memcheck,内存错误检测器
==4492== 版权所有 (C) 2002-2009 和 GNU GPL,由 Julian Seward 等人提供。
==4492== 使用 Valgrind-3.5.0 和 LibVEX;使用 -h 重新运行以获取版权信息
==4492== 命令:./mem
==4492== 父 PID:4455
==4492==
==4492==
==4492== 堆摘要:
==4492== 在退出时使用:0 个块中的 0 个字节
==4492== 总堆使用量:19,595,342 分配,19,595,342 释放,27,194,270 字节分配 ==4492==
==4492== 所有堆块都被释放——不可能有泄漏
==4492==
==4492== 对于检测到和抑制的错误计数,重新运行:-v
==4492== 错误摘要:0 个上下文中的 0 个错误(抑制:4 个来自 4 个)

但是,当代码运行时,我看到程序使用的内存有小幅稳定增长。我对这个结果有多大把握?

我使用 valgrind 运行:

valgrind --track-origins=yes --leak-check=yes
    --tool=memcheck --read-var-info=yes --log-file=error.txt`

我使用-g-march=core2 标签编译程序。

【问题讨论】:

  • 不要被操作系统静默完成的进程缓存所迷惑。

标签: c++ memory-leaks valgrind


【解决方案1】:

您需要区分内存泄漏(已分配的内存,但您丢失了所有引用)和内存占用(已分配的内存,您保留引用但忘记解除分配的内存)。

valgrind 无法检测到后者,因为 valgrind 不知道您不想再使用它。

要获取有关程序内存使用情况的一些统计信息,您可以使用 valgrind 的 massif 工具,该工具将更详细地显示您的内存分配位置。这可能有助于找到内存占用者。

【讨论】:

  • 实际上,valgrind 会检测程序退出时仍然分配的内存,对这些内存的引用仍然存在。
  • @Hasturkun:是的,但是它不会检测到您在程序运行期间忘记释放的内存,但最终会释放。就像你总是新的,而不是删除,把东西推到你认为你分配的池中。
  • 我有一张地图,其中vector <int> 作为键,set<std::tr1::shared_ptr<foo> > 作为我不断清除和重新创建的值,还有一个set <std::tr1::shared_ptr<foo> >,我也不断清除和添加值。这两个会导致内存增加吗?
  • @Yotam:如果没有更详细的分析,这很难说清楚,您可以使用 massif 进行分析。请注意,根据您用于确定程序内存使用情况的工具,由于缓存或碎片等原因,它们可能显示的内存量与所有 new/malloc 调用的总和不同。使用 massif 可以更好地了解是否是您的程序有问题。
【解决方案2】:

内存使用量的小幅增加不一定需要担心 - 这可能是您的程序正在加速并会在某个时候达到峰值。在不知道该应用程序的逻辑的情况下,很难说清楚。然而,所有分配的块都被释放了,这通常很好。

您可能想要考虑让它运行更长时间,以某种方式增加它必须做的工作(这再次取决于应用程序),以查看它是否会达到峰值或继续永远上升(或直到它耗尽虚拟内存,无论如何)。

我还要看看最后两行:

==4492== For counts of detected and suppressed errors, rerun with: -v
==4492== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4) 

您可能想用-v 运行它,只是为了检查这些抑制是什么。它们可能什么都不是,但仔细研究它并没有什么坏处。

【讨论】:

    【解决方案3】:

    您是否看到使用 top 之类的工具会增加内存使用量?根据程序的行为,如果您不断地分配和释放内存,您可能会引入导致地址空间增长的碎片。如果您让进程运行足够长的时间,它可能会稳定并停止增长。

    【讨论】:

      【解决方案4】:

      valgrind 可以检测到内存泄漏,但不会检测到内存使用率低下。您的代码中的错误可能会无缘无故地不断分配内存,然后防御性代码无论如何都会清理它。

      也就是说,我也不相信您确定进程内存使用情况的机制。幕后有很多事情要做:缓存就是其中之一。

      我称之为“不确定”。

      【讨论】:

        猜你喜欢
        • 2015-02-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 2013-02-19
        • 1970-01-01
        • 1970-01-01
        • 2020-05-01
        相关资源
        最近更新 更多