1. Technology

Should you call Free in the .Net Delphi world?

Fast Forward to Delphi for .Net - Part III.


This is the third article in the series (I, II, IV, V, VI) of articles designed with one goal in mind: to provide a quick and dirty introduction to the world of .Net programming with Delphi.

Garbage collector this, garbage collector that. Delphi developers are used to free their objects ... now the .Net GC takes care of freeing objects, the question is: when do you need/must free resources? Should you "Free" objects? Or not?


I suppose you've written tons of lines of Delphi code while developing Win32 solutions. Creating and freeing objects at run time was such an ordinary task ... In the Win32 world, any object instantiated at runtime that does not have an owner should be destroyed by a call to Free so that it can be properly disposed of and its memory released. In other words, we've all used to code sections like:

AnObject := TAnObject.Create(nil) ;
   //Do something with the object

Calling the "Free" method guaranteed that the memory occupied by AnObject would be freed when you are finished with using AnObject.

"Now" (in the .Net world) they tell you: "you do not need to Free your objects any more!". Everybody is talking about Garbage Collectors (GC).

I'm (and I suppose you are too) confused! Should I call Free, should I not? What is that garbage collector in .Net? Should I close a file / database connection after I'm done with it? What about GDI resources?

Garbage Collector

One of the new features available in the .Net framework is automatic garbage collection. The term garbage collection can be defined as management of the allocation and release of memory in an application. In other words, the .Net garbage collector (GC) completely absolves you as a developer from tracking memory usage and knowing when to free memory. After you allocate memory, the CLR determines when it is safe to free that memory.

The GC's engine determines the best time to perform a garbage collection. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations (automatically releases the memory allocated) to reclaim their memory.
What this means, is that in Delphi for .Net, you can *safely* create an object without "freeing" it.

GC is not "all mighty" - if you are using "external" resources, like database connections or network resources, you are still responsible for freeing "unmanaged" (or external) resources. The framework can track when the unmanaged resource needs to be terminated, but it does not have information on how to terminate the resource and free up the memory. In order to force the developer to free its resources, any class that operates on "unmanaged" resources must implement the Dispose (made it public) method of the IDisposable interface. In general, your implementation of the Dispose method should release all the resources that an object owns (with a call to "inherited Dispose").

Finalize, IDisposable.Dispose, Free, Destroy?

Every class in the .NET Framework inherits a method called Finalize. The bad news is that the GC calls the Finalize method (and therefore if overridden it should be protected) when the memory for the object is about to be freed. Since the method is called by the garbage collector, you have no control over when it is called.

The good news is that in Delphi for .NET, all objects implicitly implement IDisposable and redirect calls to Dispose to the Destroy destructor. This means that you do not need to implement Dispose yourself ... you can safely continue freeing resources (for objects/classes you develop) in the object's destructor "Destroy" method.

Should you call AnObject.Free?

Recall that, in Win32, calling "Free" automatically calls the destructor if the object reference is not nil. In .Net, on the on the hand, a call to Free is (as stated above) redirected to Dispose which in turn calls your destructor. What this means is that when you call Free in .Net, you actually call IDisposable.Dispose.

What this tells us, is that to free "unmanaged" (external) resources, you can safely continue using "Free" inside try-finally blocks (since you do not *generally* know whether an object you create uses "unmanaged" resources).

Conclusion: Delphi code you write remains the same, but the compiler implementation changes significantly. You do not need to be frightened of calling "Free", nor should you change all your Win32 projects you are about to pre-compile using VCL.Net!

Note: be sure to read the "Memory Management Issues on the .NET Platform" topic in the Delphi for .Net Help system.

Forward to Part IV: VCL.NET vs. FCL

©2014 About.com. All rights reserved.