我有以下示例应用程序显示了这个问题:
program FalseMemLeak;
uses
ShareMem;
var
o: TObject;
begin
o := TObject.Create; // "good" leak
RegisterExpectedMemoryLeak(o);
TInterfacedObject.Create; // bad leak
end.
我现在使用BorlndMM.dll替换和FastMMFullDebug.dll,我得到以下报告:
---------------------------
FalseMemLeak.exe: Memory Leak Detected
---------------------------
This application has leaked memory. The small block leaks are:
5 - 12 bytes: TObject x 1
13 - 20 bytes: TInterfacedObject x 1
---------------------------
OK
---------------------------
当我删除"坏"内存泄漏时,一切都很好,不会显示任何报告。但一旦出现一些意外的内存泄漏,它也会列出已注册的泄漏。
最初,我在寻找这些Indy内存泄漏时发现了这一点,并发现它们已注册,但仍在真正的内存泄漏中报告。
当我使用内置的ReportMemoryLeaksOnShutdown := True
时,它只报告TInterfacedObject
的泄漏。
那么,在完全调试模式下使用FastMM时,有没有办法过滤掉已注册的内存泄漏?
要明确这一点:这是FastMM zip附带的BorlndMM.dll,它声明这是开箱即用的替代品,它使用FastMM4并加载FastMM_FullDebugMode.dll。因此,对内存管理器的所有调用都由FastMM4处理。但不知何故,它似乎忽略了过滤掉已注册的泄漏(这些泄漏是在替换的BorlndMM.dll中用FastMM注册的——在调试该dll时可以看到)。是的,使用FastMM4.pas时不会报告已注册的泄漏,但更改这一点并不值得讨论。
在FastMM4Options.inc中有以下内容:
{$ifdef borlndmmdll}
....
{$undef HideExpectedLeaksRegisteredByPointer}
....
HideExpectedLeaksRegisteredByPointer
的定义是导致您观察到的行为的原因。重新编译已定义HideExpectedLeaksRegisteredByPointer
的替换borlandmm.dll,您预期的泄漏将从泄漏报告中被抑制。
然而,推测HideExpectedLeaksRegisteredByPointer
是未定义的。至于为什么会这样,我不确定,但我无法想象皮埃尔会意外地定义它。无论如何,也许定义HideExpectedLeaksRegisteredByPointer
是合理的。你可能想尝试一下。