In my WPF-application, I call new windows in the following way:
_newWin = new WinWorkers_AddWorker();
_newWin.WindowState = this.WindowState;
_newWin.Show();
Where _newWin
is a private Window object
.
My questions:
Should I assign a null value to _newWin
after I call _newWin.Show()
?
Will this decrease memory consumption because garbage collector / destructor will clean the null value objects earlier?
It's generally irrelevant to set a value to null. It's very rarely useful. It's occasionally harmful.
Let's consider first the simplest case:
private void DoStuff()
{
var newWin = new WinWorkers_AddWorker();
newWin.WindowState = this.WindowState;
newWin.Show();
int irrelevant = 42;
this.whoCares = irrelevant * 7;
int notRelevantEither = irrelevant + 1;
this.stillDontCare = notRelevantEither * irrelevant;
}
Here newWin
only exists in this method; it is created in it and doesn't leave the scope of the method by being returned or assigned to a member with a wider scope.
Ask a lot of people when newWin
gets garbage collected, and they'll tell you that it will happen after the line with this.stillDontCare
, because that's when newWin
goes out of scope. We could therefore have a slight win by assigning newWin = null
just after its last use, but its probably negligible.
Conceptually this is true, because we can add code that deals with newWin
anywhere up until that point, and newWin
is there for us to make use of.
In fact though, it is quite likely that newWin
becomes eligible for collection right after .Show()
. While it is conceptually in scope after then, it isn't actually used and the compiler knows that. (By "compiler" from now on I'm going to mean the entire process that produces actual running code, combining the IL compiler and the jitter). Since the memory used by newWin
itself (that is, the reference on the stack, not the object) is no longer used the compiler could use that memory for irrelevant
or something else. There being no live reference any more, the object is eligible for collection.
Indeed, if the last few methods called on an object don't actually use the this
pointer (whether directly or by using member fields) then the object can even be collected before those methods are called, because they don't actually make use of the object. If you had a method whose this
pointer was never used (again, directly or indirectly) then it might never actually be created!
Now, bearing this in mind, we can see that it really isn't going to make even that slight negligible difference that it would seem to make, if we were to assign null to the variable before the variable falls out of scope.
Indeed, it is just about possible that the assignment could even make it take longer to become eligible, because if the compiler couldn't see that that use of the variable was not going to affect the object (unlikely, but perhaps it could happen if there are try...catch...finally
blocks making the analysis more complicated), then it could even delay the point at which the object is deemed eligible. It is again probably negligible, but it is there.
So far so simple; good stuff happens if we leave well alone, and leaving well alone is easy.
It is however possible for a reference to benefit from being set to null. Consider:
public class SomeClass
{
private WorkerThing _newWin;
private void DoStuff()
{
_newWin = new WinWorkers_AddWorker();
_newWin.WindowState = this.WindowState;
_newWin.Show();
}
}
Consider here, that this time after DoStuff()
is called, _newWin
is stored in a member variable. It will not fall out of scope until the instance of SomeClass
falls out of scope. When will that happen?
Well, I can't answer that question, but sometimes the answer is important. If the SomeClass
itself is also short-lived, then who cares. It'll fall out of scope soon enough, taking _newWin
with it. If however, we assigned _newWin = null
then the object would immediately be eligible for collection.
Now, some important caveats to this:
_newWin
to be a member variable. If the example above were complete code we would move it back to being local to DoStuff()
and gain not only in this efficiency manner, but much, much more importantly in our chances of correctness, as we can't do something stupid to _newWin
from another member.Because of this, the main reason to assign null to a member variable, is simply because null has become the most appropriate value. Assigning null to a member that is no longer going to be used is generally not to release its memory ASAP but because it is no longer appropriate to use, and that becomes impossible - and clearly signalled to the rest of your code as such - when it is null.
If a reference was longer-lived than a method (and hence put in a member variable) and considerably shorter-lived than the containing object and consumed a very large amount of memory, then it's just about possible that assigning null would begin to make sense. In the extremely rare cases where that combination happens, we probably want to assign it to null to indicate that it is no longer there for the class to use anyway, so we're still not going to assign null with the purpose of releasing it to the GC. It's just about possible, but really "nah".
Garbage collection doesn't clear null objects. If you set a reference to null
you just remove a reference that was pointing to an object so that you actually lower its retain counter.
But this counter will be decreased also when an object goes out of scope with no way to be reclaimed back by code.. so what you are trying to do is useless.
The GC will choose anyway to release it only when it isn't referenced anymore, but if you show that window you will be sure that somewhere it is referenced anyway..
EDIT: as stated in comment maybe reference counting is not the way the .NET vm does (sorry but I don't use M$ platform) but the principle remains the same. Your window won't be GCed anyway since it is visible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With