0

I have created a simple project in vb.net with 2 forms "mainform" and "childform". The "mainform" has a button that simply issues childform.show() and the "childform" has a button that issues me.close() and me.dispose().

When I run the project it shows the mainform. I click the button, it opens the childform. When I click the childform button it closes the childform and all appears well.

However when I profile this using JetBrains dotMemory I take a snapshot before opening the childform and then another one after opening and closing it. I compare the snapshots and it shows an instance of childform still alive. When I look at the dependency chain I see that it's being kept alive by an instance of "MyProject+MyForms".

If I open and close the childform multiple times and resnapshot there is still the one instance of childform alive.

Showing ChildForm being retained by MyProject+MyForms

Can anyone explain what is happening here?

Gwynge
  • 140
  • 7
  • I guess I've kind of worked out what is going on here. Because I displayed the childform using childform.Show() as opposed to Dim form as new childform and form.Show() a new instance of childform, and a reference to it, is being created behind the scenes. This does rather suggest that using this shorthand way of showing a form will essentially create an object that cannot be disposed and therefore a small leak (albeit that it will only ever keep one childform and associated resources in memory). I'm not sure that this is overtly clear. I would normally use the create new / show. – Gwynge Mar 05 '16 at 10:03
  • I usually declare a child form in global space so I only have one instance of the child form in the main form. This way I don't have to reconstruct the form every time I open the form. This also retain form setting so AI can close a form and and open getting the same properties. – jdweng Mar 05 '16 at 10:18
  • 2
    Neither Close nor Dispose will make the object disappear, they just destroy unmanaged objects. The object won't disappear until the garbage collector runs. MyProject.MyForms is a VB.NET feature, it supports the quirky syntax that allows you to use the type name instead of creating an instance with the New keyword. As happens when you use, say, Form2.Show() instead of Dim frm As New Form2: frm.Show(). So this is all quite normal. – Hans Passant Mar 05 '16 at 10:19
  • Hans's comment is the correct answer. In VB.NET there is always one instance available through the class-name of the form, wether you like it or not. :) – Visual Vincent Mar 05 '16 at 11:01
  • The one instance is only created when you do the first Show() (or similar). Which makes sense but I like Hans's use of the word "quirky". I think Hans is slightly incorrect in saying "just destroy unmanaged objects" as actually a visible form with no reference will continue to be shown (so must have a reference somewhere that stops it being garbage collected), Whatever Close does must also make it eligible for garbage collection. – Gwynge Mar 05 '16 at 12:46

2 Answers2

1

You still have a reference to the child form in your main form, so the garbage collector will not erase it from memory.

Note that this has nothing to do with Dispose().

As long as there's a reference to an object, it won't be collected.

sloth
  • 99,095
  • 21
  • 171
  • 219
  • This I understand, it is the fact that a reference is created at all. When I call childform.Show() the framework is creating an instance and making it visible. I'm not sure why it stores the reference persistently though and indeed where this behaviour is documented. The answer clearly is "don't do it" but it is non-obvious. And it's non-obvious as to where it stores it – Gwynge Mar 05 '16 at 12:38
  • 1
    @Gwynge. [Here's](http://stackoverflow.com/questions/4698538/why-is-there-is-a-default-instance-of-every-form-in-vb-net-but-not-in-c) a short explanation of why it's there. Basically for transitioning vb6 code to vb.net and making it easier for vb6 programmers to make the jump to .net – Charles May Mar 05 '16 at 12:54
0

Your nested class MyForms has a field m_ChildForm where you put the reference to an instance of ChildForm class for some reason. This reference prevents ChildForm object is being collected. Set this field to null on closing the child form or do not store the reference in the class field at all.

enter image description here

Ed Pavlov
  • 2,353
  • 2
  • 19
  • 25