Memory code optimization, garbage collector theory

In my WPF application, I invoke new windows as follows:

_newWin = new WinWorkers_AddWorker(); _newWin.WindowState = this.WindowState; _newWin.Show(); 

Where _newWin is a private Window object .

My question is, should I _newWin to zero after calling _newWin.Show() ?

Will this reduce memory consumption because the garbage collector / destructor will clear objects with a zero value earlier?

Thanks.

+4
optimization c # memory destructor wpf
source share
3 answers

It usually doesn't matter to set to null. This is very rarely useful. This is sometimes harmful.

Consider the simplest case first:

 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 exists only in this method; it is created in it and does not leave the scope of the method, returning or assigning to a member with a wider scope.

Ask a lot of people when newWin gets garbage collected, and they will tell you that this will happen after the line with this.stillDontCare , because when newWin goes out of scope. Therefore, we could gain a little by setting newWin = null immediately after its last use, but probably not by much.

Conceptually, this is true because we can add code that deals with newWin anywhere to this point, and newWin where we can use it.

In fact, it is likely that newWin becomes available for collection immediately after .Show() . Although after that it is conceptually in scope, it is not actually used, and the compiler knows this. (Now using the β€œcompiler” I will understand the whole process that creates the actual current code that combines the IL compiler and the jitter). Since the memory used by newWin itself (i.e. the reference to the stack, not the object) is no longer used, the compiler can use this memory for irrelevant or something else. Where there is no link to live links, the object has the right to collect.

Indeed, if the last few methods called by the object do not actually use the this pointer (directly or using member fields), then the object can even be assembled before these methods are called, t actually use the object. If you had a method, the this pointer was never used (again, directly or indirectly), it could never be created!

Now, bearing this in mind, we can see that in fact there will not even be such a slight insignificant difference, which, apparently, would be created if we assigned a null value to the variable before the variable fell out of scope.

In fact, it is possible that the assignment may even take longer to become appropriate, because if the compiler could not see that using this variable will not affect the object (it is unlikely, but it may happen if there is a try...catch...finally blocks making the analysis more complicated), this may even delay the point at which the object is considered acceptable. This again is probably insignificant, but it is.

It is still so simple; good things happen if we leave ourselves alone, and being alone is easy.

However, a null value can be used for reference. 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 calling DoStuff() _newWin is stored in a member variable. It will not fall out of scope until an instance of SomeClass falls out of scope. When will this happen?

Well, I cannot answer this question, but sometimes the answer is important. If SomeClass itself SomeClass also short-lived, then who cares. He will soon fall out of scope, taking with him _newWin . If, however, we set _newWin = null , then the object will immediately have the right to collect.

Now, some important caveats to this:

  • First, there is no good reason that _newWin a member variable. If the above example was complete code, we would move it back to the local one in DoStuff() and get not only this efficient way, but a lot that is much more important in our chances of correctness, since we cannot do something stupid for _newWin from another member.
  • If we hold something in a member variable, this is probably for a good reason. This good reason will redefine fanaticism in relation to cleaning variables as quickly as possible.
  • Most objects simply do not take up so much memory on their own. A member variable here or there will not hurt.

Because of this, the main reason for assigning null to a member variable is simply because null has become the most appropriate. Assigning a null element that will no longer be used, as a rule, does not free up ASAP memory, but because it is no longer usable, and this becomes impossible - and is clearly signaled to the rest of your code as such - when it is null.

If the link was more durable than the method (and therefore placed in a member variable), and much shorter than the containing object and consumed a very large amount of memory, then it would be possible that assigning a null value would make sense. In extremely rare cases, when this combination occurs, we probably want to assign it null to indicate that it is no longer for the class, so we still will not assign zero in order to free it GC. It is just possible, but really "nah."

+6
source share

Garbage collection does not clear null objects. If you set the link to null , you simply remove the link pointing to the object so that you actually lower the save counter.

But this counter will also be reduced when the object goes out of scope without the possibility of returning it back by code .. so what you are trying to do is useless.

GC will choose in any case to release it only when it is no longer referenced, but if you show this window, you will be sure that somewhere it is referenced anyway ..

EDIT : as pointed out in the comment, it is possible that link counting is not the same as .NET vm does (sorry, but I do not use the M $ platform), but the principle remains the same. Your window will not be GCed, as it is visible.

+2
source share

It will not delete the object, because it will be mentioned elsewhere in the application (in the internal code). Otherwise, setting _newWin to null and getting the garbage collected will cause your window to disappear (and your program will probably crash), which does not happen.

0
source share

All Articles