有没有办法以编程方式判断FastMM是否未释放特定的内存块?


103

我试图检测是否没有释放一块内存。当然,管理器通过对话框或日志文件告诉我,但是如果我想将结果存储在数据库中怎么办?例如,我想在数据库表中有分配给定块的例程名称。

阅读FastMM的文档后,我知道自版本4.98以来,我们可能会在发生内存分配,释放和重新分配时被管理员通知。例如,OnDebugFreeMemFinish事件正在传递给我们,PFullDebugBlockHeader其中包含有用的信息。PFullDebugBlockHeader缺少一件事-如果应用程序释放了给定的块,则该信息。

除非OnDebugFreeMemFinish仅针对未释放的块调用?这是我不知道并且想找出的。

问题在于,即使挂入OnDebugFreeMemFinish事件,我也无法确定是否释放了该块。

这是一个例子:

program MemLeakTest;

{$APPTYPE CONSOLE}

uses
  FastMM4, ExceptionLog, SysUtils;


procedure MemFreeEvent(APHeaderFreedBlock: PFullDebugBlockHeader; AResult: Integer);
begin
//This is executed at the end, but how should I know that this block should be freed
//by application? Unless this is executed ONLY for not freed blocks.
end;

procedure Leak;
var
  MyObject: TObject;
begin
  MyObject := TObject.Create;
end;

begin
  OnDebugFreeMemFinish := MemFreeEvent;
  Leak;
end.

我缺少的是像这样的回调:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

浏览FastMM的源代码后,我看到有一个过程:

procedure LogMemoryLeakOrAllocatedBlock(APointer: PFullDebugBlockHeader; IsALeak: Boolean);

可以覆盖,但也许有更简单的方法?


7
我一直都知道,FastMM只能按照程序的定义来进行此检查,这是程序必须执行的-非常最后的操作-因此,在FastMM报告其代码的时间到此为止。要获得部分解决方案,您始终可以查看其来源,以了解如何标记已分配的内存。
Brian Frost

6
报告为预期泄漏?您是否按预期注册了它?另外,除非您提供了解预期寿命的复杂逻辑,否则您无法确定内存是否要在关机之前泄漏。
David Heffernan

6
如果OnDebugFreeMemFinish调用if,则意味着该块已释放。没有OnMemoryLeak活动 永远不会有这样的事件。FastMM的作用是在关闭时确定所有尚未释放的块都必须是泄漏。它不能早于此发现泄漏。
David Heffernan'1

12
每当FastMM告诉我内存泄漏时,我都会关闭工具并立即修复。如果您不这样做,那么您将很难重现泄漏。如果您确实希望登录到数据库,则需要查看CheckBlocksOnShutdown函数。另一个潜在的扩展点是,AppendEventLog但是您需要修改我怀疑的FastMM源。
David Heffernan

12
Erm只是拿起文件,解析并将其放入数据库中?
托尼·霍普金森

Answers:


2

即使存在这样的处理程序,也几乎没有用,因为在FastMM报告泄漏时,包括DB在内的所有内容都将被关闭。

因此,建议您LogErrorsToFile与中的FullDebugMode条件一起打开FastMM4Options.inc。这将为您提供带有泄漏的文本文件,稍后您可以将其解析并放入数据库中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.