Baran Topal

Baran Topal


October 2024
M T W T F S S
« Feb    
 123456
78910111213
14151617181920
21222324252627
28293031  

Categories


Some garbage collection in .NET

baranbaran

Well, for garbage collection, I can say that it is a mechanism that objects are marked for destruction when no pointers are pointing to it (Num of references is 0).

If you exit the scope of where the object was defined and you didn’t give any other object a pointer to that object then it is marked for destruction.

GC is an expensive task, and it happens only when needed.

You can call GC.Collect, but it is not reccomended.

Because the GC knows better than you when to collect, and because GC Collect is an expensive task. It means that it takes a lot of resources (CPU time).

Now, if the GC is called (automatically) every few minutes because of objects that were created and then lost all references then fine. But if you make it called every few seconds, your CPU will be busy more on freeing memory other than doing what you want it to do.

So not only it won’t improve performance in your application, but it will make it worse.

If you need deterministic freeing of resources, you cannot rely on GC, setting objects to null, etc.

Forcing GC is not the way to dispose of resources.

Using IDisposable (Dispose) interface and consider also using the “using” statement in conjunction is one way.

If you create or use objects with the IDisposable interface you should be doing this:

try
 {
 using (MyObjectWithIDisposable obj)
 {
 // Do stuff here
 }
 }
 catch (Exception e)
 {
 // Handle exceptions
 }

The ‘using’ statement will cause the Dispose method to be called as soon as the object is out of scope even if there is an exception.

Don’t worry about premature optimization and memory management. .NET will do that for you. Simply make sure you make sure you have a IDisposable interface and do like I did above or set to null when finished with an object.

There are lots of other ways for you to write slow code so don’t get focused on releasing objects from memory unless it’s already a problem. I see far more problems in fragile applications with static objects that should NOT be static.

All in all, I can say that there is no practical way to do this in .NET. .NET is designed specifically to hide the complexities of garbage collection from the application developer, for good or evil. As a result there is no direct interface that allows the developer to explicitly de-allocate the heap spaces assigned to a particular object.

Now, there are things you can do to ENCOURAGE the garbage collector to deallocate heap space, but you can’t really FORCE it to do so.

Two issues to deal with: managed resources and unmanaged resources.

1) CLR Garbage collector can clean up managed resources once they are unreachable by your application (but does not always immediately). Even calling System.GC() is no guarantee that an object will be garbage collected. GC is automatically run as heap space is needed, so usually there is no need to call it manually, and calling it manually can have a direct negative impact on application and system performance, since GC is an expensive task, you are generally better off letting the system handle it.

Setting a given object reference to NULL does not guarantee that the object will be GC’s in the next GC run, since it is possible that other references to the object exist, or that the object is a generation 2 object that has survived more than one GC sweep, and may not immediately be considered for GC.

You’ll need to read up on .NET object “generations” in order to understand the complexities. Too much to explain here:

http://www.dotnetuncle.com/Framework/58_generations.aspx

If an object has been around for a while and has been promoted to generation 2, it may take more than one GC cycle before it is considered for garbage collection.

And yes, you can force a gen2 GC run, but, again, performance may suffer, especially if you do it frequently. Calling System.GC in general is considered a sloppy practice, and should just be done on an exception basis where it is specifically required. You can certainly test it in your application to see if it helps with the problems you are experiencing, though.

2) CLR GC CANNOT clean up unmanaged resources (raw OS file handles, unmanaged memory allocations, etc.), so your classes that make use of unmanaged resources MUST clean up after themselves properly. When you talk about a “fragile” application, improper use and deallocation of non-managed resources is a common cause for that “fragility”.

If your object uses unmanaged resources, if it is properly designed it will implement the IDisposable interface, and a call to the Dispose() method should free up unmanaged resources (again, if properly designed. If not, you have a memory leak, and the application needs to be modified with a proper Dispose() method.)

If it implements the IDisposable interface, (ALWAYS) call Dispose to properly (hopefully) clean up any unmanaged resources.

If you absolutely must call GC.Collect manually (preparing to enter a critical section of code an you want to minimize interruptions from GC, perhaps), you can. Still no guarantee that GC is going to decide to clean up a specific object right then. Might not do it for a couple of cycles. To complicate matters even more, there are really two managed heaps: one for large objects and one for small objects, and they are GC’s on different schedules.

GC.Collect();
GC.WaitForPendingFinalizers();