Question

I'm trying to figure out the lifetime of the tmpTabPages in the following bit of code. Lets assume the form has an empty TabControl named MyTabControl, that there's a collection of strings called NameCollection.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For Each itm In NameCollection
        Dim tmpTabPage as New TabPage(itm.toString)

        'Add Controls to tmpTabPage

        MyTabControl.TabPages.Add(tmpTabPage)
    Next
End Sub

Since the scope of the tmpTabPage is the For/Next block, typically it's lifetime would be until the end of the block right? But since it is added to a collection that has a scope outside of the block does it get the same lifetime as the collection, or in this case the MyTabControl? Finally, if I call MyTabControl.TabPages.Clear will the tmpTabPages in the collection be destroyed or will they just sit around taking up memory?

Was it helpful?

Solution

The big deal about classes derived from Control (including TabPage) is the Dispose() method. They are immune from automatic garbage collection, Winforms keeps an internal table that maps the Handle of a control to the control reference. That's why, say, your main form doesn't suddenly get garbage collected, even though your program doesn't keep a reference to it.

Adding the TabPage to the TabControl's collection takes care of automatic disposal. The same applies for the TabControl, it would be added to the form's Controls collection. The normal chain of events is that either your program or the user closes the form. The Form class iterates its child controls and calls their Dispose() method. TabControl does the same thing in its Dispose() method, disposing the tab pages. The Windows window gets destroyed in the process, removing the Handle from that mapping table and now allowing the garbage collector to, eventually, collect the managed wrapper for the controls.

There is a nasty trap that gets many Winforms programmers in trouble. If you remove a control from its parent's collection then you get the responsibility of disposing it yourself. Removing it does not automatically dispose it. Winforms keeps the native window alive by temporarily re-parenting the control to a hidden window named the "parking window". Nice feature, it allows you to move a control from one parent to another without having to destroy and re-create the control.

But the keyword there is "temporarily". It is only temporarily if you next reparent the control. So it gets moved from the parking window to the new parent. If you don't actually reparent it then it will stay alive for ever on the parking window. Gobbling up resources until the program terminates. This is otherwise known as a leak. It can crash your program when Windows refuses to create another window when you've already created 10,000 of them.

The ControlCollection.Clear() method is especially harmful here. It does not dispose the controls, they all get moved to that parking window. If that's not intended, it rarely is, you'll have to call Dispose() on them yourself.

OTHER TIPS

Objects in .NET become eligible for garbage collection when there's no way of getting at them. In this case, there will be a way of getting at the TabPage via the TabPages collection, until either it's removed from the collection or the tab control itself becomes eligible for collection.

Now when an object becomes eligible for garbage collection, that doesn't mean it's garbage collected straight away - the garbage collection runs at various times according to some fairly complex heuristics, and there are also "generations" of memory which make things harder to predict.

But basically:

  • You don't need to worry that an object that's been added to a collection will be mysteriously collected and cause problems
  • You generally don't need to worry that objects will leak memory forever. There are certainly situations where you do need to take some active steps to make sure that an object is eligible for collection when you're no longer using it, but they're relatively rare. (Typically they are related to static variables and/or events, in my experience.)

because soemthing has a reference to the controls they will not be disposed of.

yes the lifetime would be till the end of the procedure if you were not adding a reference to them to the colelction.

the clear will remove the objects from the collection and they will get garbage collected provided there are no other references to them (which there shuoldnt be in the situation you describe)

You add only a reference of the TabPage object to the collection not the object TmpTabPage. The tmpTabPage object in this case you use it only for allocating memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top