为什么在执行我的应用程序的第一行代码之前调用TObject.Free?

ThN*_*ThN 1 memory delphi procedure

我们试图弄清楚我们的软件是否存在内存泄漏.所以,我一直在使用各种工具和程序来帮助我找到可能的内存泄漏.我使用的软件之一是AQTime.随着Delphi XE的推出,它只是一个演示.所以,我真的无法从中获得任何有用的信息.然后,我决定使用自由软件MemProof.到目前为止,它向我展示了我们的软件需要注意的许多问题.其中一个是错误.

一旦我通过MemProof启动我的程序,它就会列出2个错误,它们试图从单元文件system.pas中销毁不存在的对象.因此,当我在TObject.Free过程中实际设置断点时,它甚至在我的程序一直启动之前就会中断.在system.pas中逐步执行免费程序,我发现TIconimage试图破坏或释放自己.换句话说,在实际启动之前,我的程序中不会调用自由过程.

这是实际的免费程序:

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;
Run Code Online (Sandbox Code Playgroud)

在观察之后,我删除了断点并让程序一直运行.我的程序主窗口弹出,准备好用户输入.但是,我还发现如果我的程序的WINDOW的任何部分显示在屏幕上,则会不停地调用TObject.Free过程.我根本不明白.这是为什么?谁能解释一下?TForm如何与任何形状或形式的TObject.Free相关,因为当TForm显示在屏幕上时,不断调用过程?

提前致谢.

Dav*_*nan 11

关于为什么TObject.Free执行很多,每次销毁一个对象,任何对象,该方法都将被调用.所有类派生自TObject,它是共同的祖先,所以几乎Delphi程序中的任何动作都涉及大量的对象创建/破坏对,因此会被击中TObject.Free.

关于内存泄漏的检测,您需要内置Delphi才能解决此问题.FastMM内存管理器可以在"报告内存泄漏"模式下运行,它可以为您泄漏的任何内存提供大量诊断.

考虑以下琐碎的程序:

program Leaker;
begin
  ReportMemoryLeaksOnShutdown := True;
  TObject.Create;
end.
Run Code Online (Sandbox Code Playgroud)

这导致以下输出:

在此输入图像描述

您只需要ReportMemoryLeaksOnShutdown在应用程序的某个位置设置为True(.dpr文件的开头就像任何地方一样好).

如果您希望在报告中收到更多信息,那么您可以下载FastMM完整版本并根据您的内容对其进行配置.

然后你得到这样的输出:

A memory block has been leaked. The size is: 84

This block was allocated by thread 0x1304, and the stack trace (return addresses) at the time was:
40455E [System][System.@GetMem]
405A2F [System][System.TObject.NewInstance]
40602E [System][System.@ClassCreate]
4474C2 [Classes][Classes.TStringList.Create]
C275A3 [Main.pas][Main][Main.TMainForm.CreateAuxiliaryForms][997]
C84C8A [OrcaFlex.dpr][OrcaFlex][OrcaFlex.OrcaFlex][351]
75E633CA [BaseThreadInitThunk]
77519ED2 [Unknown function at RtlInitializeExceptionChain]
77519EA5 [Unknown function at RtlInitializeExceptionChain]

The block is currently used for an object of class: TStringList
Run Code Online (Sandbox Code Playgroud)

这真的太棒了.它告诉我泄漏的内存是在Main.pas第997行分配的,而这正是我故意泄漏的地方!