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;
Related
What is the difference between the following codes
Code 1 :
if(RecordCollections!=null){
RecordCollections.Clear();
RecordCollections=null;
}
Code 2 :
RecordCollections = null;
The code is present inside a Dispose Method , Is there any advantage over using the Clear method before making the Collection to null ? Whether it is needed at all?
Is there any advantage over using the Clear method before making the Collection to null.
Impossible to say without a good Minimal, Complete, and Verifiable code example.
That said, neither of those code snippets look very useful to me. The first one for sure would be pointless if all that the Clear() method does is to empty the collection. Of course, if it actually went through and e.g. called Dispose() on each collection member, that would be different. But that would be a very unusual collection implementation.
Even the second has very little value, and is contrary to normal IDisposable semantics. IDisposable is supposed to be just for managing unmanaged resources. It gets used sometimes for other things, but that's its main purpose. In particular, one typically only calls Dispose() just before discarding an object. If the object itself is going to be discarded, then any references it holds to other objects (such as a collection) will no longer be reachable, and so setting them to null doesn't have any useful effect.
In fact, in some cases setting a variable to null can actually extend the lifetime of an object. The runtime is sophisticated enough to recognize that a variable is no longer used, and if it holds the last remaining reference to an object, the object can become eligible for garbage collection at that point, even if the scope of the variable extends further. By setting the variable to null, the variable itself is used later in the program, and so the runtime can't treat it as unreachable until that point, later than it otherwise would have.
This last point typically applies most commonly to local variables, not fields in an object. But it's theoretically possible for the runtime to optimize more broadly. It's a bad habit to get into, to go around setting to null variables that themselves aren't going to be around much longer.
Dispose refers to a mechanism to explicitly clean up the un-managed memory, since that cannot be cleaned up using standard Garbage Collector, mostly IDisposable will be implemented by the class, which use the unmanaged API internally like Database Connection.
Standard practice is:
To also implement Finalizer along with, since Dispose is an explicit call and if missed out by caller then Finalization does take care of clean up action, though it needs 2 cycles of GC.
If a class use any of the object, as a class variable, which implements a Dispose itself, then the Dispose shall be implemented to call the Dispose on the class variable.
Regarding the code provided:
if(RecordCollections!=null){
RecordCollections.Clear();
RecordCollections=null;
}
Or
RecordCollections = null;
As this is related to cleaning up managed memory, it has little use, since GC does the main job and doesn't need it, but in my view its an acceptable practice, where class variables are explicitly nullified, which makes user vary of each and every allocation and mostly an attempt shall be made to use the method local variables, until and unless state needs to be shared across method calls. Object allocation misuse, can be much more controlled.
As far as difference is concerned, though a collection is explicitly cleared and then nullified or just nullified, the memory remains intact, till the point GC is invoked, which is un-deterministic, but in my view its not very clear, how does the GC explicitly maps the objects for collection, which are no more reachable, but for various generations, especially the higher ones (promoted objects), if an object is explicit marked as null, then GC may have to spend less / no time tracing the root / reference, however there's no explicit documentation, to explain this aspect / implementation.
MSDN recommends disposing any variable of type System.Drawing.Brush before its last reference is released. Otherwise, the resources it is using will not be freed until the garbage collector calls the Brush object's Finalize method.
As we know, local variables are destroyed automatically when the control flow goes out of the scope of the method it belongs. So, is it necessary to dispose a brush object every time if it is local?
Yes it is necessary. The flaw in your logic is when you said:
As we know, local variables are destroyed automatically when the control flow goes out of the scope of the method it belongs.
That statement is false.
When variables go out of scope, that means that they are candidates to be destroyed by the garbage collector at some point in the future, but most likely not right away. As such, if it is important to release system resources right away, you need to manually do so rather than waiting for the garbage collector to get around to doing it at some point in the future.
That is why classes which use system resources implement the IDisposable interface. They expect you to call their Dispose method when you are done with them so that they can immediately release the system resource. It's safe to assume that you should always call the Dispose method on every object that implements the IDisposable interface. If it wasn't necessary, they wouldn't implement that interface.
In the case case of the Brush class, it creates a system object via the GDI API. In order to draw filled figures via the GDI API, you must call a method to create a brush object. The API returns a handle to the brush object which you can then use to refer to that brush in later API calls. When you are done with the brush, you are supposed to call a DeleteObject API call in order to delete the object. Since each process in Windows is limited to a maximum of 10,000 GDI objects, it's very important that you delete them when you are done with them, otherwise you will run out of GDI objects and cause an OutOfMemoryException. That is why the Brush class implements the IDisposable interface--so that it can delete the underlying GDI object.
It's recommended when possible, to use a using block on all disposable objects. When execution leaves the using block, it will automatically call the Dispose method on the object for you, even if execution leaves the block due to an exception.
using(Brush b = New Brush())
{
// use the brush
}
Or
Using b As New Brush()
' use the brush
End Using
As we know, local variables are destroyed automatically
No, that's a myth. The word "destroy" is entirely inappropriate, that suggests that the program actually makes an effort to do something special with the variable in order to invoke destruction. Like throwing a brick into a glass window. That's just not how it works, the variable simply disappears in thin air. It is forgotten, as though it never existed. No brick is thrown. Ultimately the storage for the variable is overwritten by something else, it is reused. Usually in a fraction of a microsecond.
Not having to destroy a variable is what makes managed code competitive with native code. A C++ compiler for example must do it explicitly, the RAII pattern is boilerplate. Older runtime implementations that use reference counting are another example, they must ensure to explicitly count-down the reference count. That's extra code that managed code doesn't need, the garbage collector knows when a local variable is in use. It is just a bit slow at getting that job done, the reason that IDisposable exists. An attempt to add reference counting to the CLR was an abysmal failure, it could not compete with the GC.
Using the using statement is required to throw the brick.
Even though the local variable is destroyed, that is just a reference to the Brush object which is locate don the managed heap. It's not until the garbage collector sweeps the managed heap that the actual object is destroyed and the resources freed.
As a general rule: Always call Dispose on any object implementing IDisposable when you're done with the object.
The best way is often to use the using construct which will dispose correctly even in the case of exceptions:
using(var brush = CreateBrush())
{
brush.PaintSomethingNice();
}
Yes, it is necessary. In general, if it implements IDisposable, you should dispose it when you're done with it. When it goes out of scope, that only means that it is eligible for garbage collection. GC might not dispose of it for a long time, so you should dispose of it immediately.
I have a Hash table that takes strings. What is the best way to dispose them ?
After using the hash table, should I call clear and then set the object to null ?
Or would just setting the hash table object to null suffice ?
Others suggest not doing anything, and that is mostly true. You cannot dispose of it, in the classic C# sense of the term, and setting it to null should also prove unnecessary. The Garbage Collector will do its job if you let it.
So let it.
The piece of advice I have to offer that will help you let the garbage collector do its job is to limit the lifetime of the object to no longer than you need it. If the object only needs to live for a method invocation, then limit the scope of the variable and lifetime of the underlying object to that method, do not hoist it to a class member that might live longer. If the class sticks around an arbitrarily long time, that member state lives right along with it.
Declare the variable and instantiate the object where you need it, and only where you need it, and trust that the garbage collector will reclaim that memory at some point after you are through.
Setting a variable to null will not guarantee that it will be garbage collected. If other variables reference the same object the object in question will not be collected until the reference count goes to zero.
Limiting the scope of an object can help as the object is more likely to be collected after the object goes out of scope. Implementing idisposable really makes more sense for items that are not handed by garbage collection like file handles.
HashTable doesn't implement IDisposable so you can't call Dispose on it, you can assign the object null and let the garbage collector take care of it. You can't predict when it will be collected by the garbage collector, although you can force garbage collector with GC.Collect but its not recommended.
You may see: Fundamentals of Garbage Collection
Apart from this you may look into Dictionary<TKey, TValue> Class which is generic implementation of the HashTable.
GC.KeepAlive()
References the specified object, which makes it ineligible for garbage collection from the start of the current routine to the point where this method is called.
Not really sure about what GC.KeepAlive does other than simply store a reference so the Garbage Collector doesn't collect the object. But does calling GC.KeepAlive() on an object permanently keep an object from being collected? Or do you have to re-call GC.KeepAlive() every so often (and if so, how often)? I want to keep my keyboard hook alive.
When you compile .NET code for Release target, the garbage collector is really aggressive, that is, it has the potential to be.
Take this example:
public void Test()
{
FileStream stream = new FileStream(....);
stream.Write(...);
SomeOtherMethod();
}
In this example, once the call to Stream.Write has returned, this method has no more use for the stream variable, and is thus considered out of scope, which means that the FileStream object is now eligible for collection. If the garbage collector runs during the call to SomeOtherMethod that stream object might get collected.
Edit: As #Greg Beech points out in the comments, an object can be collected even if an instance method is currently executing on it.
For instance, let's say the code in FileStream.Write looks like this:
public void Write(byte[] buffer, ...)
{
IntPtr unmanagedHandle = _InternalHandleField;
SomeWindowsDll.WriteBuffer(unmanagedHandle, ...);
...
here, the method first grabs the internal field containing an unmanaged handle. The object will not be collected before this has happened. But, if this is the last field of the object, or the last instance-method of the object, being accessed in Write, before transitioning over to just P/Invoke calls, then the object is now eligible for collection.
And since FileStream probably has a unmanaged file handle (I say probably, I don't know), it probably has a finalizer as well, so the unmanaged file handle is in risk of being closed before the call to WriteBuffer has completed. That is, if the supposed implementation of .Write is as above, which it most likely isn't.
If you wish to prevent this, make the stream object live for the duration of the call to SomeOtherMethod for whatever reason, you need to insert code after the call that "uses" the object in some way. If you don't want to call a method or read a property on the object, you can use the artificial "usage" method of GC.KeepAlive to do it:
public void Test()
{
FileStream stream = new FileStream(....);
stream.Write(...);
SomeOtherMethod();
GC.KeepAlive(stream);
}
The method does nothing, but it has been flagged with attributes so that it won't be optimized away. This means that the stream variable is now in use for the duration of the call to SomeOtherMethod and the FileStream object stored in it will not get collected during that time.
That's all it does. GC.KeepAlive leaves no permanent mark on anything, it does not alter the lifetime of the object after being called, it simply adds code that "uses" the variable at some point, which prevents the garbage collector from collecting the object.
I learned about this method, or rather, the point of this method, the hard way with some code that looked like this:
public void Test()
{
SomeObjectThatCanBeDisposed d = new SomeObjectThatCanBeDisposed();
SomeInternalObjectThatWillBeDisposed i = d.InternalObject();
CallSomeMethod(i);
}
Notice that I construct an instance of an object implementing IDisposable, and in the original case, it also implemented a finalizer. I then "fished" out an object it kept track of, and the way the disposable object was set up (incorrectly) was that once the finalizer ran, it would also dispose of internal objects (which is bad). In the above code, d becomes eligible for collection once the internal object has been extracted, and once the object is collected, it finalizes itself by disposing of the object I extracted. This means that during the call to CallSomeMethod, the object passed to the method died and I couldn't understand why.
Of course, the fix for the above code was not to use GC.KeepAlive, but instead to fix the incorrect finalizer, but if the "internal object" had been an unmanaged resource, things might've been different.
Now, as for your keyboard hook, if you store your reference in a root, like a static field, a member field of an object that is also kept alive, etc. then it should not be collected out of the blue.
GC.KeepAlive (as well as GC.Collect) shouldn't be used in production code, because it doesn't solve any problems, it just creates more race conditions. They're only useful for diagnosing a problem.
If you have a managed object being used by native code so the garbage collector can't see it is still being used, you should be using GCHandle.Alloc.
EDIT: Some supporting evidence:
http://msdn.microsoft.com/en-us/library/ms182293(VS.100).aspx
http://blogs.msdn.com/ddietric/archive/2007/09/23/a-good-reason-for-calling-gc-collect.aspx
http://blogs.msdn.com/johan/archive/2007/04/20/memory-management-in-the-net-framework.aspx
http://blogs.msdn.com/clyon/archive/2006/08/28/728688.aspx
http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx
GC.KeepAlive isn't good for very much, and it's definitely only good when the usage by native code is guaranteed to end before returning, which isn't the case for a keyboard hook.
I am fascinated by the way the CLR and GC works (I'm working on expanding my knowledge on this by reading CLR via C#, Jon Skeet's books/posts, and more).
Anyway, what is the difference between saying:
MyClass myclass = new MyClass();
myclass = null;
Or, by making MyClass implement IDisposable and a destructor and calling Dispose()?
Also, if I have a code block with a using statement (eg below), if I step through the code and exit the using block, is the object disposed of then or when a garbage collection occurs? What would happen if I call Dispose() in the using block anyay?
using (MyDisposableObj mydispobj = new MyDisposableObj())
{
}
Stream classes (eg BinaryWriter) have a Finalize method? Why would I want to use that?
It's important to separate disposal from garbage collection. They are completely separate things, with one point in common which I'll come to in a minute.
Dispose, garbage collection and finalization
When you write a using statement, it's simply syntactic sugar for a try/finally block so that Dispose is called even if the code in the body of the using statement throws an exception. It doesn't mean that the object is garbage collected at the end of the block.
Disposal is about unmanaged resources (non-memory resources). These could be UI handles, network connections, file handles etc. These are limited resources, so you generally want to release them as soon as you can. You should implement IDisposable whenever your type "owns" an unmanaged resource, either directly (usually via an IntPtr) or indirectly (e.g. via a Stream, a SqlConnection etc).
Garbage collection itself is only about memory - with one little twist. The garbage collector is able to find objects which can no longer be referenced, and free them. It doesn't look for garbage all the time though - only when it detects that it needs to (e.g. if one "generation" of the heap runs out of memory).
The twist is finalization. The garbage collector keeps a list of objects which are no longer reachable, but which have a finalizer (written as ~Foo() in C#, somewhat confusingly - they're nothing like C++ destructors). It runs the finalizers on these objects, just in case they need to do extra cleanup before their memory is freed.
Finalizers are almost always used to clean up resources in the case where the user of the type has forgotten to dispose of it in an orderly manner. So if you open a FileStream but forget to call Dispose or Close, the finalizer will eventually release the underlying file handle for you. In a well-written program, finalizers should almost never fire in my opinion.
Setting a variable to null
One small point on setting a variable to null - this is almost never required for the sake of garbage collection. You might sometimes want to do it if it's a member variable, although in my experience it's rare for "part" of an object to no longer be needed. When it's a local variable, the JIT is usually smart enough (in release mode) to know when you're not going to use a reference again. For example:
StringBuilder sb = new StringBuilder();
sb.Append("Foo");
string x = sb.ToString();
// The string and StringBuilder are already eligible
// for garbage collection here!
int y = 10;
DoSomething(y);
// These aren't helping at all!
x = null;
sb = null;
// Assume that x and sb aren't used here
The one time where it may be worth setting a local variable to null is when you're in a loop, and some branches of the loop need to use the variable but you know you've reached a point at which you don't. For example:
SomeObject foo = new SomeObject();
for (int i=0; i < 100000; i++)
{
if (i == 5)
{
foo.DoSomething();
// We're not going to need it again, but the JIT
// wouldn't spot that
foo = null;
}
else
{
// Some other code
}
}
Implementing IDisposable/finalizers
So, should your own types implement finalizers? Almost certainly not. If you only indirectly hold unmanaged resources (e.g. you've got a FileStream as a member variable) then adding your own finalizer won't help: the stream will almost certainly be eligible for garbage collection when your object is, so you can just rely on FileStream having a finalizer (if necessary - it may refer to something else, etc). If you want to hold an unmanaged resource "nearly" directly, SafeHandle is your friend - it takes a bit of time to get going with, but it means you'll almost never need to write a finalizer again. You should usually only need a finalizer if you have a really direct handle on a resource (an IntPtr) and you should look to move to SafeHandle as soon as you can. (There are two links there - read both, ideally.)
Joe Duffy has a very long set of guidelines around finalizers and IDisposable (co-written with lots of smart folk) which are worth reading. It's worth being aware that if you seal your classes, it makes life a lot easier: the pattern of overriding Dispose to call a new virtual Dispose(bool) method etc is only relevant when your class is designed for inheritance.
This has been a bit of a ramble, but please ask for clarification where you'd like some :)
When you dispose an object, the resources are freed. When you assign null to a variable, you're just changing a reference.
myclass = null;
After you execute this, the object myclass was referring to still exists, and will continue to until the GC gets around to cleaning it up. If Dispose is explicitly called, or it's in a using block, any resources will be freed as soon as possible.
The two operations don't have much to do with each others.
When you set a reference to null, it simply does that. It doesn't in itself affect the class that was referenced at all.
Your variable simply no longer points to the object it used to, but the object itself is unchanged.
When you call Dispose(), it's a method call on the object itself. Whatever the Dispose method does, is now done on the object. But this doesn't affect your reference to the object.
The only area of overlap is that when there are no more references to an object, it will eventually get garbage collected. And if the class implements the IDisposable interface, then Dispose() will be called on the object before it gets garbage collected.
But that won't happen immediately after you set your reference to null, for two reasons.
First, other references may exist, so it won't get garbage collected at all yet, and second, even if that was the last reference, so it is now ready to be garbage collected, nothing will happen until the garbage collector decides to delete the object.
Calling Dispose() on an object doesn't "kill" the object in any way. It is commonly used to clean up so that the object can be safely deleted afterwards, but ultimately, there is nothing magical about Dispose, it's just a class method.