I would like to know WHY do we use "Finalization" if we want to destroy something when closing the application? doesn't closing the application frees all objects directly without calling .Free?
Thanks.
Doesn't closing the application frees all objects directly without calling Free?
No. Delphi class instances are not garbage collected and so they need to be manually destroyed.
However, if you are talking about an executable process, then it can be perfectly acceptable not to dispose of certain objects since the operating system will re-claim all resources owned by a process when that process terminates. So even though Delphi destructors don't run, the OS tidies everything up when a process terminates. It is not possible for a process to leak any system resources once it has terminated.
Note that if the unit is included in a DLL or a package then failure to destroy all objects at finalization time will lead to memory leaks, if that DLL is repeatedly loaded and unloaded into a single process.
If you know that your code only ever runs in an executable, then feel at liberty not to Free objects at finalization time. Be aware that if you are using a memory leak detection tool then doing so will result in your intentionally leaked object being treated as a memory leak. Deal with that by calling RegisterExpectedMemoryLeak.
One final point to make is that an object's destructor sometimes does more than free memory. Sometimes it can save values to a settings file, or the registry, for example. Naturally you would not want to omit running the destructor for such an object.
Adding to the final point of David Hefferman's answer: There are other resources that might need to be freed correctly, like file handlers that generate a checksum or some hardware connected to the PC that must be put in a specific state (e.g. a laser to be turned off, which is what I am currently working with).
Related
Since the process will be killed by OS and all memory allocated will be recycled anyway, is it OK not to free objects/resources in the unit finalization section?
For example,
unit Threading;
interface
implementation
var threadpool: ThreadPool;
initialization
threadpool := ThreadPool.Create;
finalization
threadpool.Free; // is it OK to remove this?
end.
Since the process will be killed by OS and all memory allocated will be recycled anyway, is it OK not to free objects/resources in the unit finalization section?
Yes, it is, probably. The system will clean up resources when the process terminates.
However, there are a couple of provisos:
Most leak detection tools check that all dynamically allocated memory is destroyed by your process before it returns control to the system. What you are proposing to do renders such tools impotent.
If your code is ever built into a dynamic library such as a DLL or a package, then the library can be unloaded, whilst the host process endures. This is a leak and can affect the viability of the host process.
Some objects require finalization to occur, sometimes with ordering constraints. Without knowing more about your class, we can't judge that.
If you remove the Free call from the finalization section then threadpool and all its sub objects will always be present in a memory leak report of your application. It would be hard to find the real memory leaks then.
Some objects may perform logging actions or delete lock files on destroy. So it can be necassary to execute all destructors.
As a (Delphi) developer you should always take care about cleaning up the heap. Otherwise you will probably lose control over the memory management. It can cost you or your company a lot of money to get the control back.
Yes, it's ok, but:
1) You can use then following construction:
ThreadPool := ThreadPool.Create;
RegisterExpectedMemoryLeak(ThreadPool);
This approach saves you from mandatory explicit order of unit referencing (so that this unit does not deinitializes before the one which uses it).
2) Otherwise you can nil the variable (or use FreeAndNil if you want System.SysUtils dependency):
finalization
ThreadPool.Free;
ThreadPool := nil;
This way you easy find who is accessing ThreadPool when it's released.
3) You can use TInterfacedObject for the implementation or wrapper of the source class.
I am trying to debug memory usage in a large application using Delphi 7. I was able to installed fastmm debug full dll and with it solve some leak problems.
I also installed the memory usage tracker, allowing me to see which blocks were allocated and of what size they are.
My question is, is there a way to find out where the blocks were allocated? I know it is possible because if the memory wasn't freed a stack trace gets printed. Is there a way to 'poke' at fastmm to get it to print the stack trace for a given allocation?
Side question: if the start address of an allocation is known, is there a way to find out which class the object is? (assuming that the allocation was for a object.
You can either:
try to use LogAllocatedBlocksToFile procedure. If its ALastAllocationGroupToLog param is less than AFirstAllocationGroupToLog or is zero, then all blocks along with their allocation call stacks are logged. However, if your app has many memory allocations, prepare to long waiting. I experienced about 4 hrs wait time and 1.5Gb resulting file. (Side-note: use glogg to view such large files)
modify FastMM4.pas so implementation's LogCallStack will be visible in interface. Or you can try to use it directly from FastMM_FullDebugMode.dll
On the side question: try to use DetectClassInstance function.
If you use FullDebugMode and enable the conditionals that will write the data to a file, then you should get exactly what you're asking for. It will write out a stack trace for every leaked allocation when the program shuts down. (If you're debugging a program with a lot of memory leaks, this can take a while. I've seem it make shutdowns last for 10 minutes or more if the leaking item is a container that holds lots of other objects.)
Considering you said in a comment that the app's memory gets cleaned up nicely on app's closing for me sounds you're looking for logical memory leaks - in other words: objects that are alive more time than needed but when the time arrive for finish the app they are cleaned because exist code to clean them.
Example:
Create an TForm using the Application as owner and the variable that references it is the global one that Delphi creates when create the form's unit.
Config the Form's CloseAction to caHide (in the OnClose event)
Show the form, operate on it
Close the form and never more use it until the app closes
Close the app, which makes Application clear all the objects it owns
So you have an logical memory leak but not an physical memory leak - which is the kind that FastMM can easily detect. Since you not intended that our hypothetical TForm live until the application finish, it semantically leaked but since it is referenced and there is code that destroys it at the end of application, to FastMM is a normal allocation.
That said appears you need not the memory dump of the memory manager, but an memory profiler.
At one point of time, I have to terminate my application developed in Delphi XE2 using Application.Terminate.
I would like to confirm, will there be any memory loss due to this?
If yes, what all possible scenarios I need to take care of?
And how to tackle them?
Calling the Application.Terminate method doesn't produce memory leaks this method is equivalent to call the PostQuitMessage function. The memory leaks are caused when the resources are not released properly. To check if you have memory leaks in your app you can set the global variable ReportMemoryLeaksOnShutdown to true.
No matter how you close a process, no memory will be leaked. When a process closes, the OS reclaims all the memory owned by the process.
Now, Application.Terminate results in an orderly shutdown, starting at the Application object. All objects owned by Application will be destroyed. If those objects in turn own other objects, the owned objects will be destroyed. However, in terms of leaking memory it is not possible for a process to terminate and leak memory. It is possible for a process to terminate and leave certain resources in an ill-defined state which is why it is often advisable to terminate a process in an orderly fashion.
I'm using Delphi 6 and I've got an application which when being shut down produces access violation errors. We use EurekaLog so I'm getting stack traces for debugging, but the errors seem to occur randomly in a different unit each time, but always when something is being freed in the finalization section.
How can I go about debugging this to see what's causing the problem? I'm not sure how to start debugging things that happen when the application is being finalised.
[Edit:] Sorry if I was unclear, perhaps a better question would be: What's the best place to start debugging with breakpoints if I only want to walk through the finalisation sections? The errors seem to arise in third party components we use (the devexpress dx/cxgrid library) so I'd like to start debugging in my code at pretty much the last point before Delphi will start calling finalise routines in other units.
This isn't much to go on, but if I had to guess, based on past experience... are you using packages or COM libraries? If you've got a global variable that's an interface, or an object whose class is declared in a BPL, and you unload the DLL/BPL before cleaning up the object/interface, you'll get access violations because your code is trying to do a VMT lookup in address space that is no longer mapped into the application.
Check for that and make sure you clean up all such variables before finalization begins.
When the application is shutting down, do not free things in the finalization section.
1) When the application shuts down, Windows frees all the application memory. You don't have to do that.
2) When the application shuts down, the memory is released, and the infrastructure is unloaded. You can't call code to close or free objects, because that code may have been already unloaded. You can't access pointers to memory, because those pointers may have already been released.
3) When you try to free things in the finalization section while the application is shutting down, you may get failures that prevent your code from finalizing, thus preventing the application from shutting down, causing a hung application and memory loss. Which is what you were trying to prevent in the first place. Don't do it.
Ok, when you are running on Win95/98, or using external processes, you may in some circumstances have to free shared resources and notify those external processes that you are shutting down. Apart from that, it all happens automagically now.
I have a MDI program. When It starts it takes 2-3MB of RAM. Then, in this program I create about 260 MDI child windows (each has a TStringGrid, a bitmap and some other controls) and display some data. The application needs about 500MB to load all those windows. If I close each MDI child manually, the application still uses 160MB of RAM. Why it doesn't return to few MB of RAM? Should I worry about this? 160MB it is A LOT for a system that has only 1GB or RAM!!
Note: I use the WORKING SET column in Task Manager to see RAM statistics. Maybe I need a better tool to read the RAM utilization. (Private Working Set is just a bit smaller than Working Set).
This is not a leak!
FastMM (set on aggressive) indicates no memory leak when I close the program. See my Answer post for additional evidence that it isn't a leak.
I release stuff
Many people told me that closing a child window only hides it. I know that. I use "Action:= caFree" to actually release the forms. Each form is responsible for releasing the controls it holds.
Answer
I have found that FastMM is responsible for this. See the answer I posted below.
Delphi 7, Win 7 32 bit
Similar posts:
Can memory be cleaned up?
When to call SetProcessWorkingSetSize? (Convincing the memory manager to release the memory)
Task Manager is not the right tool to detect memory leaks. Delphi allocates large blocks of memory and keeps them later for future use, so certain increase in allocated memory is expected even after you release all resources. Any other results (and more detailed answers) can be obtained only by using specialize memory analysis tools. AQTime is the first that comes to mind, or if you can find old but useful MemProof, it would help you a lot (MemProof is free and for memory analysis it's more handy than AQTime).
It is very well possible that FastMM does not show memory leaks upon application termination (for instance because all objects are TComponents that are owned, and the ownser frees them).
But in the mean time, while running those components can still be around, and not freed soon enough.
Did you use the FastMM unit that shows a form with the current memory usage?
< Edit >
This is the FastMMUsageTracker.pas in the directory ...\FastMM\Demos\Usage Tracker.
Use that unit, then call the ShowFastMMUsageTracker function in it.
You can refresh that form every once in a while to see how your memory consumption grows.
I have put a FastMMUsageTrackerProject sample on-line, including an update of FastMM4 that makes it easier to check and debug memory leaks:
the form in the FastMMUsageTracker unit is now resizable, and the controls in it anchor in the right way
there is a new FastMmBootstrapUnit unit making debugging specific memory leaks easier
Something I had at hand last week, was a 3rd party DLL, which was not written in Delphi.
The DLL had a memory leak using Windows GlobalAlloc calls, which are not tracked by FastMM.
NB: I'm about to post an update to FastMM on
--jeroen
Answer:
I just removed FastMM from my project and the program returned to few MB after freeing all those child windows. Many may argue that this is not a misbehavior and that FastMM is doing this in order to do some kind of kinky memory optimizations. They may be true. However, it may be good for MY application but it may not be good of other running applications.
So, at least we know who causes this. I worried to a whole day that may program is leaking RAM like an old bucket. I am relieved now.
UPDATE:
To confirm that this behavior is generated by FastMM (as suggested by Barry Kelly) I created a second program that allocated A LOT of RAM. As soon as Windows ran out of RAM, my program memory utilization returned to its original value.
(Note: I am not saying there is a bug in FastMM!)
My program is not leaking. Problem solved.
The main limitation of FastMM's memory leak tracing is that it can only run when you shut down the program. It could be that you're still holding references to objects or other data that gets cleaned up when you shut down the program, but stays around until then.
For example, when you close the MDI child windows, do you call Free or Release on them, or just make them disappear? If they're hidden but not freed, they'll still be in memory.
If you close an MDI form it is not freed automatically. Use Action = caFree (google for that) to make sure the form is also freed.