Manually destroy C# objects
You don't manually destroy .Net objects. That's what being a managed environment is all about.
In fact, if the object is actually reachable, meaning you have a reference you can use to tell the GC which object you want to destroy, collecting that object will be impossible. The GC will never collect any object that's still reachable.
What you can do is call GC.Collect()
to force a general collection. However, this almost never a good idea.
Instead, it's probably better to simply pretend any object that doesn't use unmanaged resources and is not reachable by any other object in your program is immediately destroyed. I know this doesn't happen, but at this point the object is just a block of memory like any other; you can't reclaim it and it will eventually be collected, so it may just as well be dead to you.
One final note about IDisposable
. You should only use it for types that wrap unmanaged resources: things like sockets, database connections, gdi objects, etc, and the occasional event/delegate subscription.
If the object is not reachable then you can call GC.Collect()
and the object will be destroyed. The concept of IDisposable
has nothing to do with the CLR and is mostly for user code to implement to perform additional disposal logic. Calling Dispose() on an object will not free the object itself from memory, though it may very well dispose any resources that this object references.
I should add that while what I said is a way to achieve this, in 99.9999% of applications you should never call GC.Collect()
because it'll often degrade the performance of your application instead of improving it.
Although you can trigger garbage collection (you need to trigger GC for all generations because you can't be sure which generation the finalizable object is in) you cannot necessarily force finalization of a particular object. You can only depend upon assumptions about how the garbage collector works.
Furtnermore, since finalization happens on its own thread, you should call WaitForPendingFinalizers after triggering garbage collection.
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
As was noted by others, this can actually hurt your application's performance because unnecessarily invoking the GC can promote otherwise short-lived objects into higher generations which are more expensive to collect and are collected less frequently.
Generally speaking, a class that implements a finalizer (destructor) and does not implement IDisposable is frowned upon. And anything that implements IDisposable should be calling it's finalizer logic and supressing itself from finalization at garbage collection.
Jeff Richter recently posted a nice little trick for receiving a notification when garbage collection occurs.
Another great article on Garbage Collector Basics and Performance Hints by Rico Mariani (MSFT)