FastMM仅报告内存泄漏和/或内存分配吗?

3
我正在使用FastMM调试程序,它报告了很多内存泄漏,但实际上它们大部分都是合法的内存分配,而不是真正的内存泄漏。例如:
A memory block has been leaked. The size is: 20

This block was allocated by thread 0xD44, and the stack trace (return addresses) at the time was:
404902 [System.pas][System][@GetMem][3693]
406597 [System.pas][System][TObject.NewInstance][11044]
406B2A [System.pas][System][@ClassCreate][12121]
60A1D2 [CtrlObjs.pas][Ctrlobjs][TConnObj.Create][430]
61703B [Control.pas][Control][TControlMgr.FindLinks][854]
60ACB2 [CtrlObjs.pas][Ctrlobjs][TControlObject.FindLink][746]
60E2A3 [CtrlObjs.pas][Ctrlobjs][TDelayControl.EvalPulse][2105]
60E4C0 [CtrlObjs.pas][Ctrlobjs][TDelayControl.Evaluate][2193]
6102D4 [CtrlObjs.pas][Ctrlobjs][TLineControl.Evaluate][3155]
60ABF1 [CtrlObjs.pas][Ctrlobjs][TControlObject.ActiveCount][711]
6105D8 [CtrlObjs.pas][Ctrlobjs][TLineControl.ActiveCount][3261]

The block is currently used for an object of class: TConnObj

TConnObj是一个经常用于创建对象并在程序不再需要时销毁的类。然而,FastMM报告它实际上是内存泄漏。那么,在查看FastMM内存泄漏日志文件时,如何区分哪个是哪个呢?

1个回答

8
如果FastMM报告它是一个泄漏,那么它确实是一个泄漏。
您已经创建了一个对象,并在程序终止之前未能销毁它。通常这是由于您代码中的一个简单错误导致的。也许您省略了一个try/finally来保护该对象的生命周期。
如果它是一个全局作用域的对象而没有被销毁,那么您可以在程序终止时简单地销毁它。或者您可以调用RegisterExpectedMemoryLeak来表明您不打算销毁该对象。但只有在有意泄漏对象时才使用它。不要用它来掩盖不是有意的泄漏。
但归根结底,FastMM不会撒谎。如果它说您正在泄漏,请相信它。

1
我经常有缓冲池,其中包含数千个对象,我在应用程序退出时没有明确释放它们。我不喜欢在内部传递所有这些缓冲区字段等指针。我想我会关闭泄漏报告 :( - Martin James
2
@MartinJames,我希望没有人需要在你的代码上工作。这会使真正的泄漏检查变得不可能。 - Francesca
1
@martin 并不是说你必须要写成千上万次的 RegisterExpectedMemoryLeak 调用。 - David Heffernan
@François - 通常,每秒钟,一个计时器会将每个对象池和队列计数的级别转储到状态栏。我知道在运行时是否有任何泄漏或双重释放的池化对象,而无需等待任何内存管理器信息。即使连接了20000个客户端和八个繁忙线程的服务器,所有我的应用程序都会立即安全关闭,因为对象池超过了所有线程-操作系统首先停止所有线程,然后释放内存。我的应用程序不会出现内存泄漏,因为我在启动后不创建任何对象。 - Martin James
@DavidHeffernan - 我该如何创建1000个对象并注册它们的数据成员?正如我向Francios解释的那样(抱歉,不知道如何打出cedilla),我不需要内存管理器的详细信息,但如果我能轻松地让它工作,那么我会接受它的输出。 - Martin James
删掉那个评论中的问题 - 它有点脱离了原帖的上下文。我会另外发一个问题。 - Martin James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接