Microsoft KB Archive/190511

= BUG: UserControl Containing Array of Controls Leaks Memory =

Article ID: 190511

Article Last Modified on 10/15/2002

-

APPLIES TO


 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



This article was previously published under Q190511



SYMPTOMS
If a UserControl containing an array of controls is used, and one of the elements of the control array is assigned to an object, the following error may occur with repeated loading and unloading of the form that hosts the UserControl:

"Error 7: Out of memory"



RESOLUTION
There are two possible resolutions to this issue:


 * Create controls individually rather than in an control array.
 * Create a Public method in the user control that releases allocated memory and then call the method from the Form that hosts the control array during the Form Unload event. Note that you cannot do this in the control's Terminate event because this event does not fire in this situation.



STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.



MORE INFORMATION
Sample code is provided in this article to illustrate both the problem and its workaround.

To view the behavior of both the problem and the workaround, use a system tool that allows you to view available memory. On Windows NT 4.0 or Windows 2000, launch the Task Manager and watch the memory meter on the performance tab while running the application. On Windows 95, Windows 98, or Windows Me, use the Resource Meter utility.

The problem happens in both the development environment and as a compiled application.

Step-by-Step Example
 Start a new Standard EXE project in Visual Basic. Form1 is created by default. Place a TextBox on Form1. Text1 is created by default. Now, enter the number '3' in the Text property. This value represents the number of times the called Form loads and unloads. Place a CommandButton (Command1) on Form1. Change Commad1's Caption property to "Demonstrate Problem." NOTE: When this sample is completed, clicking this button will demonstrate the problem. Place a second CommandButton (Command2) on Form1. Change Command2's Caption property to "Workaround." NOTE: When this sample is completed, clicking this button will demonstrate the workaround.  Add the following code to the Form1 code window: Option Explicit

' This code demonstrates the problem.

Private Sub Command1_Click Dim i As Long, n As Long n = Text1.Text For i = 1 To n           Form2.Show Unload Form2 Set Form2 = Nothing Next i     End Sub

' This code demonstrates the workaround. Private Sub Command2_Click Dim i As Long, n As Long n = Text1.Text For i = 1 To n           Form3.Show Unload Form3 Set Form3 = Nothing Next i     End Sub

 From the Project menu, click Add User Control (UserControl1).</li> Add three ComboBox controls to UserControl1 as a Control Array. To do this: place a ComboBox from the Toolbox onto UserControl1, creating Combo1. Copy Combo1 (CTRL+C) and then Paste it (CTRL+V). A dialog box will ask if you want to create a Control Array; choose Yes. Then, paste a third ComboBox onto UserControl1. Note that the Properties window now shows the three ComboBox controls as Combo1(0), Combo1(1), and Combo1(2).</li>  Add the following code to the UserControl1 code window: Option Explicit Dim MyCombo As ComboBox

Private Sub UserControl_Initialize Set MyCombo = Combo1(0) End Sub

Private Sub UserControl_Terminate MsgBox "Terminate" End Sub

</li> From the Project menu, click Add User Control (UserControl2).</li> Add three ComboBox controls to UserControl2 as a Control Array, as demonstrated in step 7.</li>  Add the following code to the UserControl2 code window: Option Explicit Private MyCombo As ComboBox

Private Sub UserControl_Initialize Set MyCombo = Combo1(0) End Sub

Public Sub CleanUp Set MyCombo = Nothing End Sub

</li> From the Project menu, click Add Form (Form2).</li> Place an instance of UserControl1 onto Form2. Note that you must close the UserControl design window before you can place it onto Form2.</li> Add a third form to the project (Form3). From the Project menu, select Add Form.</li> From the Toolbox, place UserControl2 onto Form3.</li>  Add the following code to the Form3 code window: Option Explicit

Private Sub Form_Unload(Cancel As Integer) UserControl21.Cleanup End Sub

</li> Compile and Run your Project.</li></ol>

To illustrate the problem, click on the "Demonstrate Problem" CommandButton. If you are using a system tool that allows you to view available memory, you will see that memory usage increases every time you click the Demonstrate Problem CommandButton. Memory is not recovered after unloading Form2 or after setting Form2 to Nothing. Notice that UserControl1's Terminate event does not fire in this situation (the message box does not display).

To illustrate the workaround, click on the Workaround CommandButton. If you are using a system tool that allows you to view available memory, you will see that memory usage remains the same every time you click the Workaround CommandButton. Memory is recovered after unloading Form3. The workaround here is to release the memory from within UserControl2's CleanUp procedure, which is called during Form3's Form_Unload procedure.

Keywords: kbbug kbpending kbcontrol KB190511

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.