I have found on our code base code like this:
if (disposing)
{
....
}
Marshal.ReleaseComObject(comObject)
As the comObject is in fact a .Net object (a RCW, right?) is it safe to call it from the Finalizer?
Is it possible that it has been already released?
As Hans Passant said:
No, that is not safe, an RCW already has its own finalizer. Which
first of all makes the code completely unnecessary. More severely,
since finalization order is not deterministic you might be calling
ReleaseComObject() on an object that is already destroyed
So the call must be inside the if (disposing).
Related
Trying to understand how an object is reclaimed. Read here that the order of objects being reclaimed is not guaranteed.
For example, my class has the following code -
class MyClass: IDisposable
{
private List<string> _fileNames;
// some other code and methods here with constructor
~MyClass()
{
Dispose(false);
}
private void Dispose(bool dispose)
{
foreach (string file in _fileNames)
{
// log something with dispose
File.Delete(file);
}
}
}
Does it mean that when the GC tries to reclaim this object, there is no guarantee that the _fileNames is still populated with strings and not null? Or, can one still use the list of strings above to free up resources? In the link posted, it mentions -
'The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already been finalized when the finalizer of Object A starts.'
So does it mean that the list may no longer be useful in the Dispose (assuming dispose is false)?
If the method call comes from a finalizer, only the code that frees
unmanaged resources should execute. The implementer is responsible for
ensuring that the false path doesn't interact with managed objects
that may have been disposed. This is important because the order in
which the garbage collector disposes managed objects during
finalization is non-deterministic.
Implementing Dispose
But it's moot because you shouldn't implement finalizers. Pretty much ever.
Consider your example. If someone fails to call Dispose, your object will eventually become unreachable, and eventually GC will figure that out and try to run your finalizer. However it's not guaranteed to ever run, and it's not guaranteed to run in any particular timeframe. It could be hours.
So what is really gained by adding the finalizer? Not much.
Failing to call Dispose on an IDisposable is a bug. So the only time the finalizer will run is when there's a bug. So it might be a good idea to have a finalizer that just throws an exception, crashing your program, so you can find and fix the whatever didn't call Dispose(). But having a finalizer try to clean up after buggy code is usually a bad idea.
This question already has answers here:
What is IDisposable for?
(6 answers)
Closed 7 years ago.
I come from a C++ background and have trouble understanding the point of IDisposable objects (and the point of many other things in .NET). Why is a Dispose function necessary in the first place? Whatever it does, why not do that in the destructor of the class? I understand it cleans up managed resources, but isn't that what a destructor is supposed to do? I understand that
Using ( var obj = new SomeIDisposableObject )
{
// ...
}
is the equivalent of
var obj = new SomeIDisposableObject;
// ...
obj.Dispose();
but how does that save any typing? And if C# has a garbage collector, which it does, then why are we ever worried about disposing resources?
Is IDisposable/Using/etc. a Skeet-approved concept? What does he think of it?
IDisposable is nothing special. It's just an interface that makes you have a Dispose() function. IDisposable won't clear anything or destroy objects. A call to Dispose() does nothing if that function does nothing.
The use of IDisposable is a pattern. It's so important that it gets its own language construct (the using block), but it's just a pattern.
The difference with a destructor, is that in .NET, the destructor is non-deterministic. You never know when the garbage collector will collect your object. You don't even know if it even will (unlike using delete in C++, which is deterministic).
So IDisposable is there for deterministically releasing unneeded references (and releasing unmanaged resources). The "disposed" object will remain in memory after you call Dispose until the garbage collector decides to collect it (at which point, the "destructor" will be called, unless you explicitly tell it not-to), if it ever decides to.
That's the main difference to using "destructors" (or finalizers, as they are called in C#).
As for the why do we need it:
Managed references to other objects prevent objects to be collected by the garbage collector. So you need to "release" those references (by, for example, setting the variables that reference those objects to null).
Objects in .NET can use unmanaged resources, if they use native libraries. For example, every control or bitmap in a Windows.Forms application uses a Win32 handler, which is unmanaged. If you don't release those resources, you may reach the handle limit in Windows if using any big application, easily. Also, if you need interoperability with any non-.NET API, you'll more likely have to allocate unmanaged memory (with the use of, for example, Marshal.AllocHGlobal), which will need to be released at some point: that point is generally the Dispose() function of the IDisposable, which must be called explicitly (or by using a using block).
As for the using block, it's more equivalent to:
var myObject = new MyDisposableClass();
try
{
...
}
finally {
myObject.Dispose();
}
So it does indeed save typing
Using a using block doesn't only call the .Dispose method; it calls the .Dispose method when you leave the block, however you leave it. So, if your code crashes, it will still call Dispose. The actual code would be closer to:
try
{
var obj = new SomeIDisposableObject;
// ...
}
catch (exception ex)
{
}
finally
{
obj.Dispose();
}
Additionally, destructors don't always fire when you expect them to. I've had a few bugs where the destructor is called after the program has apparently exited, and tried to access resources that no longer exist. Since you don't know when it will be called, it's difficult to fix this.
There are several discussions here on StackOverflow about what to do if my object manages other managed objects that implement System.IDisposable.
Note: Below I am not talking about unmanaged code. I fully understand the importance of cleaning up unmanaged code
Most of the discussions say that if your object owns another managed object that implements System.IDisposable, then you should also implement System.IDisposable, in which case you should call the Dispose() of the disposable objects your object holds. This would be logical, because you don't know whether the disposable object you own uses unmanaged code. You only know that the creator of the other object thought it would be wise if you'd call Dispose as soon as you don't need the object anymore.
A very good explanation of the Disposable pattern was given here on StackOverflow, edited by the community wiki:
Proper use of the IDisposable interface
Quite often, and also in the mentioned link I read:
"You don't know the order in which two objects are destroyed. It is entirely possible that in your Dispose() code, the managed object you're trying to get rid of is no longer there."
This baffles me, because I thought that as long as any object holds a reference to object X, then object X will not and cannot be finalized.
Or in other words: as long as my object holds a reference to object X I can be certain that object X is not finalized.
If this is true, then why could it be, that if I hold the reference to my object until my finalize, the object I refer to is already finalized?
The truth is somewhere between the two:
The object can't be garbage collected, so the possibility of the object no longer "being there" isn't true
An object can be finalized when there are no longer any references to it from other non-finalizable objects.
If object X refers to object Y, but both are finalizable, then it's entirely possible for object Y to be finalized before object X, or even for them to be finalized concurrently.
If your assumption were correct, then you could create two objects which refer to each other (and have finalizers), and they could never be garbage collected because they could never be finalized.
Quoting Eric Lippert's, When everything you know is wrong, part two
Myth: Keeping a reference to an object in a variable prevents the
finalizer from running while the variable is alive; a local variable
is always alive at least until control leaves the block in which the
local was declared.
{
Foo foo = new Foo();
Blah(foo); // Last read of foo
Bar();
// We require that foo not be finalized before Bar();
// Since foo is in scope until the end of the block,
// it will not be finalized until this point, right?
}
The C# specification states that the runtime is permitted broad latitude to
detect when storage containing a reference is never going to be accessed
again, and to stop treating that storage as a root of the garbage collector.
For example, suppose we have a local variable foo and a reference is written
into it at the top of the block. If the jitter knows that a particular read is
the last read of that variable, the variable can legally be removed from the
set of GC roots immediately; it doesn’t have to wait until control leaves the
scope of the variable. If that variable contained the last reference then the
GC can detect that the object is unreachable and put it on the finalizer queue
immediately. Use GC.KeepAlive to avoid this.
Why does the jitter have this latitude? Suppose the local variable is
enregistered into the register needed to pass the value to Blah(). If foo
is in a register that Bar() needs to use, there’s no point in saving the
value of the never-to-be-read-again foo on the stack before Bar() is
called. (If the actual details of the code generated by the jitter is of
interest to you, see Raymond Chen’s deeper analysis of this issue.)
Extra bonus fun: the runtime uses less aggressive code generation and
less aggressive garbage collection when running the program in the
debugger, because it is a bad debugging experience to have objects
that you are debugging suddenly disappear even though the variable
referring to the object is in scope. That means that if you have a bug
where an object is being finalized too early, you probably cannot
reproduce that bug in the debugger!
See the last point in this article for an even more horrid version of
this problem.
If done properly, you don't have to worry about disposing objects that are already disposed. Every implementation of Dispose should just not do anything if it had been disposed before.
So indeed, you cannot know whether any child objects have been disposed or finalized already (because the order of finalization is random, see other post), but you can safely call their Dispose method anyway.
In most cases when Finalize is called on an object which holds references to one or more IDisposable objects, one or more of the following will apply:
The other object has already been cleaned up, in which case calling Dispose is at best useless.
The other object has been scheduled to be finalized as soon as possible, but hasn't yet, in which case calling Dispose is probably unnecessary.
The other object's cleanup code cannot be used safely within the finalizer threading context, in which case calling Dispose could likely be disastrous.
The other object is still being used by code elsewhere, in which case calling Dispose could likely be disastrous.
There are a few situations where code knows enough about IDisposable objects that it's dealing with to know either that none of the above apply, or that it should trigger cleanup despite the above; those situations, however, may be better served by having the other objects supply a method other than Dispose which the object being finalized can call.
After all the answers, I created a small program that shows what Jodrell wrote (thank you Jodrell!)
An object can be garbage collected as soon as it will not be used, even if I have a reference to it
This will only be done if not debugging.
I wrote a simple class that allocates unmanaged memory and a MemoryStream. The latter one implements System.IDisposable.
According to everyone on StackOverflow I should implement System.IDisposable and free the unmanaged memory as well as Dispose the managed memoryStream if my Dispose is called, but if my finalizer is called I should only free the unmanaged memory.
I write some diagnostic console messages
class ClassA : System.IDisposable
{
IntPtr memPtr = Marshal.AllocHGlobal(1024);
Stream memStream = new MemoryStream(1024);
public ClassA()
{
Console.WriteLine("Construct Class A");
}
~ClassA()
{
Console.WriteLine("Finalize Class A");
this.Dispose(false);
}
public void Dispose()
{
Console.WriteLine("Dispose()");
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
Console.WriteLine("Dispose({0})", disposing.ToString());
if (!this.IsDisposed)
{
if (disposing)
{
Console.WriteLine("Dispose managed objects");
memStream.Dispose();
}
Console.WriteLine("Dispose unmanaged objects");
Marshal.FreeHGlobal(memPtr);
}
}
public bool IsDisposed { get { return this.memPtr == null; } }
}
This program follows the Dispose Pattern as described numerous times, a.o. here in stackoverflow in Proper use of the IDisposable interface
by the way: for simplicity I've left out exception handling
A simple console program creates the object, doesn't use it, but keeps the reference to it and forces the garbage collector to collect:
private static void TestFinalize()
{
ClassA a = new ClassA() { X = 4 };
Console.WriteLine("Start Garbage Collector");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Done");
}
Note that variable a holds a reference to the object until the end of the procedure. I forget to Dispose, so my finalizer should take care of disposing
Call this method from your main. Run the (release) build from the debugger and run it via a command prompt.
If run from the debugger then the object stays alive until the end of the procedure, so until after the garbage collector has finished collecting
If run from a command prompt, then the object is finalized before the procedure ends, even though I still have a reference to the object.
So Jodrell is right:
unmanaged code needs Dispose() and Finalize, use Dispose(bool)
Managed disposable objects need Dispose(), preferably via Dispose(bool). In Dispose(bool) only call Dispose() of managed objects if disposing
don't trust the debugger: it makes that objects are finalized on different moments than without debugger
I am reading now about the Dispose and the Finalize method on the CLR ( 4.0 )
I dont understand something ...
If I add an implementation of Finalize ( ~className1 ) to my code => then the Finalize List have pointer to the object instance that in the managed heap.
Now, Lets say i did not implement the Finalize ( ~className2 ) and i just implemented the IDisposable interface on my code - Is thie object will have pointer from the Finalize List ?
No. If an object doesn't have a finalizer, it will not be in the finalize queue.
Reference: MSDN
The garbage collector keeps track of objects that have Finalize methods... Each time your application creates an object that has a Finalize method, the garbage collector places an entry in the finalization queue that points to that object.
Basically, the longer an object exists, the less the garbage collector will check whether it's still referenced in the code. That means that unused objects can often still be in memory although they haven't been referenced anymore for a long time. Also, if you want to explicitly tell an object to clean up its resources, use the Dispose method. I'd suggesst calling GC.SuppressFinalize(this) in its implementation, and calling the Dispose method in the finalizer as well. That way, if the user forgets to call Dispose, which should not but can happen, the object's resources will get freed-up eventually.
I have a object and simply want to destroy it on some event. How to call the destructor in XNA?
Set the object to null and the Garbage Collector will pick it up on it's next run.
As a side note, if the object is something that you create often (enemies, bullets etc..), then you may want to use a pool instead of deleting the object. This would mean that object is recycled, and thus, the garbage collector is called less often which will increase performance.
While your mileage may vary, my preference is to use IDisposable and Dispose() of objects I no longer need. This is esp. true when you are using unmanaged resources, but having the Dispose() set up declares intent.
See this resource on GC.SuppressFinalize for a good example of how to implement IDisposable.
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
Set reference to this object to null.
After setting the object to null, if you want for some reason the object to be collected immediately, call GC.Collect().
What kind of object? If is an Disposable/IDisposable you should call object.Dispose()
Otherwise, you can just use object=null, and it will be 'cleaned' automatically. This is not C you're working in ;)
If your 'object' is actually a complex class or something with more objects in it, you might want to consider making it an IDisposable class.
If the object holds any unmanaged resources then implement IDisposable (and use using or call Dispose() on it when you're done with it).
If it doesn't hold unmanaged resources then the garbage collector will claim it "at some point" when there are no more references to it.
GC.Collect() will make the garbage collector collect and it will "destroy" your object if there are no references to it. This is not a very good idea since it has performance implications (it takes time and promotes other objects into a higher generation making them last longer in memory before being reclaimed).
Why do you need the object destroyed at a certain fixed time?
What you want to do is call GC.SuppressFinalize() if you are handling the cleanup yourself... Usually you use GC.SuppressFinalize() within an IDisposable class. See this code example for the common use of IDisposable:
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
If you really need to have it Garbage Collected right away:
var myObj = new MyObject();
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(myObj);
But I caution you that you should really let the object go out of scope, and let the GC collect the objects naturally. The .NET runtime is very efficient at managing memory as long as you don't try to do it's job.
EDIT
After reviewing the comments, I see you forgot to leave an important piece of information, in that you were binding the object in question to other objects methods. This means that the object that you are trying to finalize is not going to finalize until the method used to watch the event has finalized, thus keeping around a ton of extra objects in memory.
What you can do to break this strong reference is use an object called WeakReference. Or use lambdas to to break the strong references.
See this for an example of using a WeakReference
http://msdn.microsoft.com/en-us/library/system.weakreference.aspx
Or you can do something like this:
dym.cas += (x, y, z) => gameTime.ElapsedGameTime(x,y,z);
instead of
dym.cas += gameTime.ElapsedGameTime;