What is the importance of clearing the collection before disposing - c#

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.

Related

Is disposing a local brush variable necessary?

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.

Why structs cannot have destructors?

What is best answer on interview on such question you think?
I think I didn't find a copy of this here, if there is one please link it.
Another way of looking at this - rather than just quoting the spec which says that structs can't/don't have destructors - consider what would happen if the spec was changed so that they did - or rather, let's ask the question: can we guess why did the language designers decide to not allow structs to have 'destructors' in the first place?
(Don't get hung up on the word 'destructor' here; we're basically talking about a magic method on structs that gets called automatically when the variable goes out of scope. In other words, a language feature analogous to C++'s destructors.)
The first thing to realize is that we don't care about releasing memory. Whether the object is on the stack or on the heap (eg. a struct in a class), the memory will be taken care of one way or another sooner or later; either by being popped off the stack or by being collected. The real reason for having something that's destructor-like in the first place is for managing external resources - things like file handles, window handles, or other things that need special handling to get them cleaned up that the CLR itself doesn't know about.
Now supposed you allow a struct to have a destructor that can do this cleanup. Fine. Until you realize that when structs are passed as parameters, they get passed by value: they are copied. Now you've got two structs with the same internal fields, and they're both going to attempt to clean up the same object. One will happen first, and so code that is using the other one afterwards will start to fail mysteriously... and then its own cleanup will fail (hopefully! - worst case is it might succeed in cleaning up some other random resource - this can happen in situations where handle values are reused, for example.)
You could conceivably make a special case for structs that are parameters so that their 'destructors' don't run (but be careful - you now need to remember that when calling a function, it's always the outer one that 'owns' the actual resource - so now some structs are subtly different to others...) - but then you still have this problem with regular struct variables, where one can be assigned to another, making a copy.
You could perhaps work around this by adding a special mechanism to assignment operations that somehow allows the new struct to negotiate ownership of the underlying resource with its new copy - perhaps they share it or transfer ownership outright from the old to the new - but now you've essentially headed off into C++-land, where you need copy constructors, assignment operators, and have added a bunch of subtleties waiting to trap the unaware novice programmer. And keep in mind that the entire point of C# is to avoid that type of C++-style complexity as much as possible.
And, just to make things a bit more confusing, as one of the other answers pointed out, structs don't just exist as local objects. With locals, scope is nice and well defined; but structs can also be members of a class object. When should the 'destructor' get called in that case? Sure, you can do it when the container class is finalized; but now you have a mechanism that behaves very differently depending on where the struct lives: if the struct is a local, it gets triggered immediately at end of scope; if the struct is within a class, it gets triggered lazily... So if you really care about ensuring that some resource in one of your structs is cleaned up at a certain time, and if your struct could end up as a member of a class, you'd probably need something explicit like IDisposable/using() anyhow to ensure you've got your bases covered.
So while I can't claim to speak for the language designers, I can make a pretty good guess that one reason they decided not to include such a feature is because it would be a can of worms, and they wanted to keep C# reasonably simple.
From Jon Jagger:
"A struct cannot have a destructor. A destructor is just an override of object.Finalize in disguise, and structs, being value types, are not subject to garbage collection."
Every object other than arrays and strings is stored on the heap in the same way: a header which gives information about the "object-related" properties (its type, whether it's used by any active monitor locks, whether it has a non-suppressed Finalize method, etc.), and its data (meaning the contents of all the type's instance fields (public, private, and protected intermixed, with base-class fields appearing before derived-type fields). Because every heap object has a header, the system can take a reference to any object and know what it is, and what the garbage-collector is supposed to do with it. If the system has a list of all objects which have been created and have a Finalize method, it can examine every object in the list, see if its Finalize method is unsuppressed, and act on it appropriately.
Structs are stored without any header; a struct like Point with two integer fields is simply stored as two integers. While it is possible to have a ref to a struct (such a thing is created when a struct is passed as a ref parameter), the code that uses the ref has to know what type of struct the ref points to, since neither the ref nor the struct itself holds that information. Further, heap objects may only be created by the garbage-collector, which will guarantee that any object which is created will always exist until the next GC cycle. By contrast, user code can create and destroy structs by itself (often on the stack); if code creates a struct along with a ref to it, and passes that ref it to a called routine, there's no way that code can destroy the struct (or do anything at all, for that matter) until the called routine returns, so the struct is guaranteed to exist at least until the called routine exits. On the other hand, once the called routine exits, the ref it was given should be presumed invalid, since the caller would be free to destroy the struct at any time thereafter.
Becuase by definition destructors are used to destruct instances of classes, and structs are value types.
Ref: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
By Microsoft's own words: "Destructors are used to destruct instances of classes." so it's a little silly to ask "Why can't you use a destructor on (something that is not a class)?" ^^

How does reassigning a disposable object variable work?

In C# when reassigning a disposable object variable with a new object, how does it work in the memory? Will the memory space occupied by the old object simply be overwritten by the new object? Or do I still have to call Dispose() to release the resources it uses?
DisposableThing thing;
thing = new DisposableThing();
//....do stuff
//thing.Dispose();
thing = new DisposableThing();
In this case you have one slot / reference and two instances of an IDisposable object. Both of these instances must be disposed indepedently. The compiler doesn't insert any magic for IDisposable. It will simply change the instance the reference points to
A good pattern would be the following
using (thing = new DisposableThing()) {
// ... do stuff
}
thing = new DisposableThing();
Ideally the second use of thing should also be done within a using block
It works the same as any other assignment: = does not care about IDisposable or do any magic.
The object initially assigned to the variable will have to have Dispose invoked manually (or better yet, with using) as required. However, it may not always be correct to call Dispose at this point: who owns the object and controls the lifetime?
Will the memory space occupied by the old object simply be overwritten by the new object?
Does not apply. Variables "name" objects. An object is itself and a variable is a variable - not the object or "location in memory". (See Eric Lippert's comment bellow: the preceding is a high-level view of variables while Eric's comment reflects variables more precisely in C# implementation, spirit, and terminology.)
Variables only affect object lifetimes insomuch as they can* keep an object from being reclaimed (and thus prevent the finalizer from [possibly eventually] running). However, variables do not control the objects semantic-lifetime -- an object may be Disposed even when not reclaimable -- or eliminate the need to invoke Dispose as required.
Happy coding.
When dealing with disposable objects that extend beyond simple scopes -- the objects may be assigned to many different variables during their lifetime! -- I find it best to define who "takes control" which I annotate in the documentation. If the object lifetime is nicely limited to a scope then using works well.
*A local variable itself is not necessarily sufficient to keep an object strongly reachable as it is possible that the variable/assignment is aggressively optimized out if not used later from the same scope. This may plague objects like timers.
It is possible, and common, for multiple references to the same IDisposable object to exist. There is nothing wrong with overwriting or destroying all but one of those references, provided that one reference will have Dispose called on it before it is destroyed.
Note that the purpose of IDisposable.Dispose isn't actually to destroy an object, but rather to let an object which has previously asked other entities to do something on its behalf (e.g. reserve a GDI handle, grant exclusive use of a serial port, etc.), notify those entities that they no longer need to keep doing so. If nothing tells the outside entities that they no longer need to keep doing something on behalf of the IDisposable object, they'll keep doing it--even if the object they're doing it for no longer exists.

How to call destructor in C # XNA

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;

Setting an object to null vs Dispose()

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.

Categories

Resources