【问题标题】:How to find "weak" memory leaks如何找到“弱”内存泄漏
【发布时间】:2021-10-22 06:57:36
【问题描述】:

在 C++ 程序中,我有时会遇到 "weak" 内存泄漏问题。我的意思是,一些对象会积累资源,但最终这些对象会被正确销毁并释放它们的内存,因此这些泄漏不会使用传统的内存调试工具(如 valgrind 或地址清理器)出现。

一个典型的例子是一个写得很糟糕的缓存,它保留了程序开始时所有的缓存结果。它会永远增长,但它的内存会在程序结束时,即缓存被销毁时回收。

如何调试这个?是否有工具可以查看程序分配的最大对象在哪里?转储分配内存的当前状态(包括调用堆栈)?看看哪些对象在增长?我正在使用 Linux,但我也对其他平台感兴趣。

【问题讨论】:

  • 否,因为通常这种分配方案是在 malloc 和 family 之上处理的。这些库需要提供一些方法来从中提取有用的使用信息。不会有通用的灵丹妙药解决方案。
  • Valgrind 的 massif 应该对此有用。
  • 很难说,因为(例如)不断增长的容器可能是预期的。在这些情况下,内存浪费(所谓的“弱”内存泄漏)与预期行为之间的区别可能很难确定。
  • @dratenik 这听起来很有趣,我必须去挖掘!
  • 我写了一个工具(heob; 仅限 Windows),它有一个特殊的模式额外用于这种内存泄漏:1)从禁用泄漏记录开始,让程序进行第一次迭代它的工作量,所以一切都被初始化。 2) 启用泄漏记录,并让程序对其工作负载进行另一次迭代。 3) 再次禁用泄漏记录,并再次让程序对其工作负载进行另一次迭代。 4) 显示启用了泄漏记录的迭代的所有剩余内存块(应该包含那些“弱”内存泄漏)。

标签: c++ memory-leaks


【解决方案1】:

如果可以选择其他平台,我会推荐 Windows 上的 Visual Studio。
它具有强大的分析选项,包括用于内存使用的选项。
https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage

在调试时,您可以拍摄快照以查看正在使用内存的位置。
您还可以在不同时间拍摄内存使用情况快照并进行比较。

【讨论】:

  • 这似乎是一个不错的选择,不幸的是,我目前有很多设置工作......
【解决方案2】:

您可以使用分析器,例如英特尔 VTune(这也适用于 Linux)来跟踪应用程序的内存消耗。在 VTune 中,您可以查看一段时间内的内存消耗,并选择一个时间窗口以查看在该窗口期间内存分配的位置。

如果您的应用程序正确分配和释放大量内存,并且只有一小部分被释放得太晚,仍然很难检测到此类问题。在这种情况下,您需要检查大量分配/解除分配,然后才能找到坏的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2011-01-09
    • 2013-04-04
    • 2017-01-23
    • 2018-04-07
    相关资源
    最近更新 更多