1

I have been asking myself for quite a while, when exactly objects and variables go out of scope and are garbage collected. Also what the difference between reference and value types is in this regard.

For example if I use

Private Sub Foo()
  Dim ob as Integer = 1
End Sub

it is my understanding that the variable goes out of scope when the Sub has run its course and the related memory is freed again. I thought that this was the same with references. However I can do the following

Private Sub Foo()
  Dim frm1 as New Form1
  frm1.Show()               'Edit made here!
End Sub

and the related form is opened stays open even though the sub is over immediately. Therefore there seem to be references that are kept open somehow, so the new form instance is not disposed of. Maybe there is something special about forms. But what about some other random object?

Private Sub Foo()
  Dim ob as New MyRandomClass
End Sub

Will this object persist like the form or is it disposed?

Could someone shed some light about the details of scope and the differences between variables, objects and maybe Forms (which are not really straightforward in VB.net compared to C# in my opinion).

Jens
  • 6,275
  • 2
  • 25
  • 51
  • 1
    Out of scope and removed from memory are not the same thing necessarily. Which are you more concerned with? – Brian Driscoll Mar 17 '14 at 14:07
  • In this case, also the exact difference ;-) I understand that out of scope means the name is no longer accessible. Is the variable garbage collected in this case in the next run? – Jens Mar 17 '14 at 14:10

1 Answers1

3

In .NET it is very important to understand the difference between value types and reference types. Value types are mostly primitive types that are allocated on the stack. This memory is freed once the method is exited. This is the case in your first sample (Integer is a value type).

In contrast, classes are reference types. This applies to both the Form and MyRandomClass. For reference types, the memory is allocated on the managed heap. Only the reference to the memory that points to the location on the heap is allocated on the stack. If all references to an object on the heap go out of scope, the memory on the heap is also freed by the Garbage Collector at a later point in time.

This is what happens in your 3rd sample: you allocate an object on the heap with a single reference named ob pointing to it. At the end of the method, the reference ob is freed, but the object on the heap will still exist until it is deallocated by the Garbage Collector.

However, your second sample is indeed a special case. You create a new instance of Form1 and store the reference in frm1. When calling Show the form becomes a part of the user interface of the application. As it is a non-modal form, it is shown on the screen but the execution of your application does not wait until the form is closed. The user interface thread of your application is used to handle the messages for the form until it is closed. So there are some other references to the form though the one you used to create it initially has gone out of scope already. After the form has been closed, the memory is freed as there are no active references to it anymore.

Markus
  • 20,838
  • 4
  • 31
  • 55
  • Oh that makes sense. I did not know the `Show()` method was static. That explains the difference pretty nicely. So the shown forms are handled explicitly in the background somehow. However I can do the same example #2 in C#, and if the `Show` method wasn't static in C# how would the reference be kept alive? – Jens Mar 17 '14 at 14:41
  • @Jens: I clarified my answer; there is no static Show method. In VB.NET there is a default instance of a form that is accessed by `FormClassName.Show` for backward compatibility. Forms do not differ from regular classes in the sense of memory management. The only thing that is different is that there is a default instance in VB.NET. I suppose the default instance is created on the first call and freed at the end of the process. Other instances are created upon instantiation and freed by the GC once all references went out of scope. – Markus Mar 17 '14 at 14:47
  • Oh damn, I am sorry about it but I made a mistake in my original post: In the second example I wanted to write `frm1.Show()` but have written `Form1.Show()` which makes that example quite different and your answer completely valid. However in the case I intended: The frm1 objects seems to persist after the Sub is completed. Is the reference kept alive by the form being shown? – Jens Mar 17 '14 at 14:56