问题描述
我们正在尝试确定软件中是否存在内存泄漏.因此,我一直在使用各种工具和程序来帮助我发现可能的内存泄漏.我使用的软件之一是AQTime.随Delphi XE一起提供时,它只是一个演示.因此,我真的无法从中获得任何有用的信息.然后,我决定使用免费软件MemProof.到目前为止,它已经向我展示了我们软件中的许多问题,需要引起注意.其中之一是错误.
We are trying to figure out if we have memory leaks in our software. So, I have been using various tools and programs to help me find possible memory leaks. One of the software I used was AQTime. As it came with Delphi XE, it was only a demo. So, I was not really able to get any useful information from it. Then, I decided to use free software, MemProof. So far, it has shown me many issues with our software that requires attention. One of which is an error.
当我通过MemProof启动程序时,它列出了2个错误,试图从单元文件system.pas中销毁不存在的对象.因此,当我实际上在TObject.Free过程中放置一个断点时,它甚至在我的程序完全启动之前就中断了.逐步执行system.pas中的Free过程,我发现TIconimage试图破坏或释放自身.换句话说,在实际启动之前,不会从程序内部调用自由过程.
As soon as I start my program through MemProof, it lists 2 errors, which is attempting to destroy non-existent object from the unit file, system.pas. So, when I actually put a break point within TObject.Free procedure, it breaks even before my program started all the way. Stepping through the procedure Free in system.pas, I found out that TIconimage is trying to destroy or free itself. In other word, free procedure is not invoked from within my program prior to actually starting up.
这是实际的免费程序:
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
在观察之后,我删除了断点,并让程序一直运行.我的程序主窗口弹出,可供用户输入.但是,我还发现,如果屏幕上显示了程序的WINDOW的任何部分,则会不停地调用TObject.Free过程.我一点都不明白.这是为什么?谁能解释?当屏幕上显示TForm时,该过程会不断被调用,因此TForm与TObject.Free的关系如何(以任何形状或形式)?
After that observation, I removed the breakpoint and let the program run all the way. My programs main window popped up ready for user input. However, I also found out that TObject.Free procedure is invoked non-stop if any part of my program's WINDOW is displayed on the screen. I don't understand that at all. Why is that? Can anyone explain? How is TForm is related to TObject.Free in any shape or form as the procedure is constantly invoked when the TForm is displayed on the screen?
谢谢.
推荐答案
关于为什么TObject.Free
执行很多,每当一个对象被销毁时,任何对象都会被调用.所有类都是从TObject派生而来的,它是共同的祖先,因此Delphi程序中几乎所有动作都涉及大量对象创建/销毁对,因此将命中TObject.Free
.
Regarding why TObject.Free
executes a lot, every single time an object is destroyed, any object, that method will be called. All classes derive from TObject, it's the common ancestor, so almost any action in a Delphi program involves large numbers of object create/destroy pairs and consequently will hit TObject.Free
.
关于检测内存泄漏,您已将所有所需的内容内置到Delphi中以解决此问题. FastMM内存管理器可以在报告内存泄漏"模式下运行,它将为您提供大量有关您泄漏的内存的诊断信息.
Regarding detection of memory leaks, you have all you need built in to Delphi to solve this. The FastMM memory manager can be run in "report memory leaks" mode and it will give you loads of diagnostics of any memory that you leak.
考虑以下简单程序:
program Leaker;
begin
ReportMemoryLeaksOnShutdown := True;
TObject.Create;
end.
这将导致以下输出:
您只需要在应用程序中的某个位置将ReportMemoryLeaksOnShutdown
设置为True(.dpr文件的开头与其他地方一样好).
You just need to set ReportMemoryLeaksOnShutdown
to True somewhere in your app (the start of the .dpr file is as good a place as any).
如果您希望在报告中获得更多信息,则可以下载完整版的FastMM 并根据您的内心需求对其进行配置.
If you wish to receive more information in the report then you can download the full version of FastMM and configure it to your heart's content.
然后您将得到如下输出:
Then you get output like this:
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
这真是太好了.它告诉我,泄漏内存是在Main.pas行997中分配的,而这正是我故意泄漏的地方!
It's truly wonderful. It tells me that the leaking memory was allocated in Main.pas line 997, and that's precisely where I put my intentional leak!
这篇关于为什么在执行应用程序的第一行代码之前调用TObject.Free?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!