Some of the other answers to this question contain a disappointing amount of misinformation, while others greatly complicate the problem. There are many misconceptions related to garbage collection in .NET, and theories tied up here certainly do not help this problem.
First of all, using profiling memory in Windows Task Manager is a huge mistake . You will receive serious invalid information , and trying to change your application in accordance with this information will only lead to a worse situation, and not for the better. If you suspect that you have performance problems (and it is very doubtful that most applications will actually experience any problems), you need to invest in a proper memory profiler and use them instead.
Secondly, the whole point of garbage collection is that you do not need to worry about it. . And you do not need to worry not only about this, but you should not worry about it either. When writing applications targeted at the .NET Framework, you should not do or try to manage manual control manually. Resist the temptation to tinker with the internal workings of the garbage collector, and firmly put your fingers in your ears when someone tells you to call GC.Collect manually to make garbage collection happen. I suppose I should never have said, but there is hardly ever a reason for this. I much more often suspect code that manually causes garbage collection than anything else.
Why shouldn't you manually reference the garbage collection? Well, beyond the obvious argument that it defeats the whole point of using a managed language in the first place, because garbage collection is a very slow and expensive process . You want it to work as little as possible to maintain maximum performance. Fortunately, the programmers who implemented the garbage collection algorithms are much smarter and more experienced than you or me: they designed it to run only when it is needed, and not more often than that. You will not see the advantages of working with him more often, but you will see the disadvantage. This should be completely opaque to you as a programmer.
The only exception is when you work with unmanaged objects that are not collected or managed by the garbage collector. You can recognize these objects because they all implement the IDisposable interface , which provides the Dispose method for releasing unmanaged resources. On objects that expose this method, you must call it as soon as you finish using the object. Or even better, wrap the declaration and use the object in a using statement , which automatically processes the removal of the object, regardless of what (even if the exception is thrown in the code where you use the object, for example).
Of course, you will notice that some standard Windows Forms library objects implement the IDisposable method. The ubiquitous Form class , for example, provides the Dispose method. However, this does not necessarily mean that you are responsible for manually deleting these objects. In general, you only need to explicitly call the Dispose method on objects that you explicitly create - it's easy to remember, right? Objects created automatically by the Framework are also automatically destroyed by the Framework. For example, the controls that you place on the Form object at design time are automatically deleted when their container form is located. And the Form objects themselves are automatically deleted when they are closed. This is especially true for the question raised in your question. The documentation for the Form.Close method tells us the following:
When the form is closed, all resources created inside the object are closed and the form is deleted.
[.,]
Two conditions when the form is not placed on Close is when (1) it is part of an application with a multiple document interface (MDI) and the form is not visible; and (2) you displayed the form using ShowDialog . In these cases, you will need to manually call Dispose to mark all the garbage collection form controls.
Note that in general, you will not have to manually call Form.Dispose manually from your code. It is not possible for the user to close the MDI child form when the MDI parent is not visible, and if you accidentally closed the form in code when its parent is invisible, you can simply insert a call to Form.Dispose . When you display a form as a modal dialog using the ShowDialog method, you can conveniently wrap its creation and use it in the using statement.
Now recall that just calling the Dispose method on an object only frees up unmanaged resources and puts the object as available for garbage collection. It does not immediately release the memory declared by this object. This is important because this is exactly what your memory profiling attempts were aimed at. You know that objects are located because you mention that variables become inaccessible to you (you say that you are "losing your values"). This is because you cannot access located objects. This does not necessarily mean, however, that the memory they claimed has been completely released. Performing this task is the garbage collector that we have already installed, you should not monkey. He will wait until the memory is freed until the application runs or desperately needs to reuse that memory. Otherwise, it will defer collection and , still OK .