4

最近有人建议(我的程序从不释放内存。为什么?)我的程序泄漏了一些内存。我将 FastMM 设置为积极,当我关闭程序时它不会报告内存泄漏。

无论如何,我想知道是否存在 FastMM 未检测到的内存泄漏?

更新:我个人不使用 Win API 来分配内存。但我担心我使用的一些 3rd 方组件(不是很多)可能会使用它。你能告诉我 FastMM 无法拦截的所有可能的 API 调用吗?我将在我的代码中搜索它们。谢谢。


Delphi 7, Win 7 32 bit
FastMM 4.97
我对接口不感兴趣。

4

6 回答 6

4

FastMM 是 Windows 内存管理之上的一层。显然,如果您(或某些组件或其他)使用 Windows API 分配内存,那么这种分配会绕过 FastMM,您将无法跟踪它。顺便说一句,Delphi 内存管理器自己使用该 API 来分配内存块。因此,如果您需要查看该级别的分配,FastMM 是不够的 - 您必须使用 AQTime 和类似工具(正如我在上一个问题中建议的那样)。

于 2010-12-18T12:10:39.857 回答
3

我从来不知道 FastMM 无法检测到内存泄漏。

于 2010-12-18T12:07:15.630 回答
3

不,只有由 FastMM 分配的内存泄漏。

编辑: 也许答案看起来很包装,但事实并非如此!如果有人检查FastMM haw 是不是可以看到内存分配的每个指针都被推入(并在 FreeMem 中弹出)到一个堆栈(有更多堆栈,取决于内存大小)所以在关闭应用程序结束时FastMM 只检查堆栈,如果堆栈中有东西,如果是,则报告内存泄漏!

于 2010-12-18T12:14:50.577 回答
3

有几个可能的原因:(适用于任何内存管理器)

  • 您的主程序循环泄漏内存,但这样做是为了在关机时释放
    • 最简单的情况是记录到备忘录。备忘录变得越来越大,但在关机时被销毁。
  • 内存是在 fastmm 的控制之外分配的
    • 直接从windows分配
    • 在 dll 等中分配的内存。
  • 堆碎片。内存管理器保持分配的大块(例如,因为它仍然包含一小部分分配)。结果:应用程序不使用它,但它也没有发布到操作系统。运行时/内存管理器保留它。
    • fastmm 应该对这种现象更有弹性,但有疑问尝试打印 heapmanager 信息以查看是否是这种情况。
于 2010-12-18T18:28:04.180 回答
2

FastMM 不会检测未通过 FastMM 的内存分配泄漏。

这可以包括来自您使用的 3rd 方库或 DLL 的 GlobalAlloc 调用。
编辑:微软的 MSDN 有一个很好的内存分配方法列表

这实际上是我在回答您之前的 FastMM 问题时提到的问题。

您可以使用VMMap之类的工具来跟踪 FastMM 无法检测到的内存泄漏。

——杰伦

于 2010-12-18T21:18:47.890 回答
2

已经有很多好的答案了,但是还有一点没有提到......

自从内存被释放以来,大多数内存泄漏检测器都无法检测到很多“泄漏”,但是在它不再使用之后。例如,对象堆叠在 TObjectList 中。对象被放入对象列表中,但是在您使用完它们之后,您不会释放它们。当对象列表也被销毁时,它们也将被销毁(例如,当应用程序关闭时,假设 OwnsObject=True)。由于对象实际上已被释放,因此对象不会“泄漏”,但仍会使您的应用程序随着时间的推移使用越来越多的内存。

FastMM 不会报告这些,因为它只进行“全面运行”分析。要检测这些,您需要一个允许进行部分运行的内存泄漏检测器,即分析执行期间 A 点和 B 点之间“泄漏”的内容。Eugene 提到的 AQTime 允许这种检查。但是请注意,这需要进行一些分析,因为这会产生许多误报(几乎所有“realloc”操作都将被标记为泄漏)。

于 2010-12-18T21:50:32.597 回答