Persistant User controls and out of memory exception

dmvprof

Member
Joined
Dec 9, 2010
Messages
12
Programming Experience
Beginner
I have a Winform application that I am using with WCF and SQL. Part of the program that the users use to create a report will dynamically create custom user controls and place a reference to them into a hashtable that I maintain. Then as the user navigates through the report by selecting nodes on a treeview, I load and unload the User Controls into a panel.

Here is the code I use to create them and place them into the Collection

Code:
       ucIncidentInstance = New ucIncidentMR(IncidentReport, IncidentReportGUID)
        ucIncidentInstance.Tag = "IncidentMR"
        ucIncidentInstance.Dock = DockStyle.Fill
        Globals.ControlTable.Add(IncidentReportGUID, ucIncidentInstance)
        Globals.GlobalNode.Nodes.Add(IncidentReportGUID, "Incident Report")
Here is the code that moves them in and out of the Panel on the form as the user navigates through the treeview

Code:
        If Globals.ControlTable.ContainsKey(e.Node.Name) Then
            panelMain.Controls.Clear()
            panelMain.Controls.Add(CType(Globals.ControlTable(e.Node.Name), UserControl))
        Else
            If e.Node.Name = "MainNode" Then
                panelMain.Controls.Clear()
            End If
        End If
And here is the code I use in the forms ?Closing? event to try to clean up the memory when the User closes this case. I?ve done it with and without the ?.Dispose()? line and the ?= Nothing? line. This code does get executed but doesn?t seem to help.

Code:
        For Each item As DictionaryEntry In Globals.ControlTable

            If item.Key = IncidentReportGUID Then
               Dim myControl As ucIncidentMR
                myControl = CType(Globals.ControlTable(item.Key), ucIncidentMR)
                myControl.Dispose()
                myControl = Nothing
            End If

        Next

When I go into a memory profiler, the controls stay in memory even though the form that created them has been unloaded from memory. The profiler reports that the control listed above has held memory of 8818k. When a report is closed and another is opened, the held memory for this control increases by 8818k. And continues to increase by that amount for each report that is opened. As you can imagine, people opening and closing a lot of reports eventually get an out of memory exception.
 

dmvprof

Member
Joined
Dec 9, 2010
Messages
12
Programming Experience
Beginner
Thanks for responding.

These are custom controls of different types.

They are only shown one at a time.
 

dmvprof

Member
Joined
Dec 9, 2010
Messages
12
Programming Experience
Beginner
More info. I have one type of custom control that does get removed when the form closes I have no idea what is different aout it.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,169
Location
Sydney, Australia
Programming Experience
10+
First of all, you shouldn't be using a Hashtable. Use a generic Dictionary. I guess your keys are Strings and, if there's no more specific type, your values are all UserControls at least. That means that you can use a Dictionary(Of String, UserControl). When it's time to clean up, this should be all you need:
For Each item In myDictionary
    item.Value.Dispose()
Next

myDictionary.Clear()
 

dmvprof

Member
Joined
Dec 9, 2010
Messages
12
Programming Experience
Beginner
First of all, you shouldn't be using a Hashtable. Use a generic Dictionary. I guess your keys are Strings and, if there's no more specific type, your values are all UserControls at least. That means that you can use a Dictionary(Of String, UserControl). When it's time to clean up, this should be all you need:
For Each item In myDictionary
    item.Value.Dispose()
Next

myDictionary.Clear()
I'm following your suggestion, and will post results, but in the meantime, I'm just curious about why not a hashtable?
 

dmvprof

Member
Joined
Dec 9, 2010
Messages
12
Programming Experience
Beginner
I'm following your suggestion, and will post results, but in the meantime, I'm just curious about why not a hashtable?
I replaced the hash table with the dictionary, but the behavior didn't change.

I'm still hung up on the fact that one of the controls is being removed and several others remain. I don't see anything obviously different with it.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,169
Location
Sydney, Australia
Programming Experience
10+
I'm following your suggestion, and will post results, but in the meantime, I'm just curious about why not a hashtable?
For the same reason that you should use a List(Of T) and not an ArrayList. It's not .NET 1.1 any more.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,169
Location
Sydney, Australia
Programming Experience
10+
I replaced the hash table with the dictionary, but the behavior didn't change.

I'm still hung up on the fact that one of the controls is being removed and several others remain. I don't see anything obviously different with it.
What exactly do you mean by "removed"?
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,324
Location
Norway
Programming Experience
10+
It is also worth noting that disposing a control does not immediately free the memory of that object, only when the garbage collector takes the round does that happen - if the object space can be claimed at that time. Disposing frees unmanaged resources and mark the object disposed and to not be finalized, which makes the eventual GC process faster.
 
Top Bottom