Re: VB6 not releasing Memory when Form is Unloaded

From: Kevin (kevinp_at_cfl.rr.com)
Date: 12/21/04


Date: Tue, 21 Dec 2004 23:14:55 GMT

You're probably already doing this but.....

I create a recordset and then display the results in a DataGrid using
these lines:

pstrSQL = "SELECT * FROM sometable ORDER BY fldName"
rs.Open pstrSQL, db, adOpenKeyset, adLockOptimistic, adCmdText
Set Grid1.DataSource = rs

Then in the Form_QueryUnload event I use these lines:

rs.Close
Set rs = Nothing

I haven't had any memory problems, but I'm not dealing with 20k
records. I usually deal with up to 10k records.

On Tue, 21 Dec 2004 12:58:13 -0500, "John Kotuby" <jkotuby@snet.net>
wrote:

>Thanks Mike,
> (and also Kevin, Shane, Larry, Bob and Bob for your input)
> It appears that we can try to "minimize" the damage by clearing the
>contents of Private form variables as you suggest. That seems to be one of
>the major causes of memory usage in our project, especially when upon form
>load, an ADO Recordset variable is populated immediately and displayed in a
>Grid. This is the "Browse All" option for locating records in a table (which
>does not need to be the default but currently is) . If 20,000 records exist
>in the Recordset, a subset of 12 (or so) fields from every record is pulled.
>This results in a memory penalty of 6mb each time that form is loaded and
>unloaded. Apparently VB is including that Recordset as part of the Form
>footprint? More likely we are not releasing the contents of Recordset
>variables properly when the form is unloaded.
>
>If, however, the same form is loaded using the "Begins With" option, only
>about 1 mb of memory is used, until the User runs a query to pull records
>after the form is loaded. With this scenario, when the form is unloaded,
>only the orignal 1 mb footprint of memory is retained. Apparently the Data
>cache is released in this case. But still, every time that same form is
>reloaded an additional 1 mb of memory is again claimed and held. I don't
>think we will be able to do better than that.
>
>Anyway, I will try setting all form referencnces (including the implicit
>form reference itself) to Nothing from within the calling Form ( Module,
>Class...etc.).
>
>Thanks again.
>
>P.S. I hope that VB.NET does a better job of memory management.
>
>"Mike Harrington" <msnews@alouria.com> wrote in message
>news:OsO$36u5EHA.2804@TK2MSFTNGP15.phx.gbl...
>> John,
>>
>> You are right... VB's handling of forms is "less than ideal" to say it
>> nicely. Information about the form always remains after you load it the
>> first time, and keeps recalling this "footprint" each time you load it
>> again
>> (as far as I can tell). There are other issues as well when dealing with
>> forms.
>>
>> If you have a module-level (private) variable in a form, it will retain
>> its
>> value even if you use the command "Unload FormX" Example:
>>
>> FORM 1
>> ======
>>
>> Option Explicit
>>
>> Public Sub Command1_Click()
>> Load Form2
>> Form2.Show
>> End Sub
>>
>> FORM 2
>> ======
>>
>> Option Explicit
>>
>> Private msMyString As String
>>
>> Public Sub Form_Load()
>> Text1.Text = msMyText
>> End Sub
>>
>> Pub Sub Command1_Click()
>> msMyText = Text1.Text
>> End Sub
>>
>> Public Sub Command2_Click()
>> Me.Hide
>> Unload Me
>> End Sub
>>
>> With the above example, after you close the form2 and unload it, if you
>> reopen it, the variable msMyString will have retained it's value. To stop
>> the form from retaining the values, you must have the line "Set Form2 =
>> Nothing" on Form1. This resets the values, but there is a surprising
>> little
>> twist. The values are reset, but VB6 still keeps the old values in memory
>> even though they aren't being used. If you have a lot of data saved in a
>> private variable on a form, this could be a major problem. To get around
>> this, you need to use both "Unload FormX" and followed by "Set FormX =
>> Nothing" to clear them. Here's an example of what I mean:
>>
>> Form1
>> =====
>>
>> Option Explicit
>>
>> Private Sub Command1_Click()
>> Dim f As Form2
>>
>> Set f = New Form2
>>
>> f.Show vbModal
>>
>> Unload f
>> Set f = Nothing
>> End Sub
>>
>> Form2
>> =====
>>
>> Option Explicit
>>
>> Private msMyString As String
>>
>> Private Sub Form_Load()
>> msMyString = String$(100000, " ")
>> End Sub
>>
>> Private Sub Command1_Click()
>> Me.Hide
>> End Sub
>>
>> Information about Form2 will always remain in memory, but at least all the
>> data is actually cleared. There is no way as far as I know to stop it
>> from
>> "caching" the information about the form. I have several projects that
>> use
>> well over 70-100 forms and this becomes a "major" problem. If it was a
>> truly major problem (hundreds of forms) you could always write the code to
>> create them using the Windows API, but you might as well move to C++ at
>> that
>> point and save yourself a trip through hell.
>>
>> I don't know if any of that was actually useful to you, but hopefully it
>> gives you some insight. I'd love to hear if anyone has a way of actually
>> forcing VB to COMPLETELY unload a form from memory after it's done being
>> used (although I don't think it can be done).
>>
>> -Mike
>>
>> "John Kotuby" <jkotuby@snet.net> wrote in message
>> news:e9v8DTs5EHA.4004@tk2msftngp13.phx.gbl...
>>> We have a large MDI VB6 app. The majority of the Forms in the app are MDI
>>> children, Each of the MDI children are derived from a class module. Each
>>> form class module consists of multiple Tabs and uses multiple User
>> Controls
>>> (not compiled ocx's) as well as many standard MS and quality 3rd party
>>> controls. A typical form class may have several hundred controls and also
>>> reference other classes (ADO class, USER class, SESSION class, MESSAGE
>>> class, etc.)
>>>
>>> The forms are opened in the Sub Main of the Parent Class for the form
>>> (separate and distinct from the Form class itself) as below.
>>>
>>> ====================================================
>>> Public Sub Main()
>>> '|
>>> '| STANDARD CODE: DO NOT REMOVE OR CHANGE
>>> '|
>>>
>>> Call Me.Setup '| SETUP FOR ALL BASE1 EXCEPT FORM
>>>
>>> Call ISSetupForm '| SETUP FOR FORM
>>>
>>> Call Me.STDrec.STDFrm.Frm.Show '| EXECUTE THE FORM
>>>
>>>
>>> End Sub
>>> =====================================================
>>>
>>> To illustrate how the form object ended up in Me.STDrec.STDFrm.Frm see
>>> the
>>> following code:
>>>
>>> ================================================
>>> Private Sub ISSetupForm()
>>> '|
>>> '| STANDARD CODE: DO NOT REMOVE OR CHANGE
>>> '|
>>>
>>> Dim oFRM As PLA_FRM_B1APP_ORDEDIT
>>> Set oFRM = New PLA_FRM_B1APP_ORDEDIT
>>>
>>> Me.STDrec.STDFrm.Frm = oFRM
>>>
>>> oFRM.BASE1app = Me
>>> oFRM.STDsec = Me.STDsec
>>> oFRM.STDFrm = Me.STDrec.STDFrm
>>>
>>> Me.STDrec.Frm = oFRM
>>>
>>> End Sub
>>> ===================================================
>>> Notice oFRM is a local variable here.
>>> Needless to say there are a number of class objects referenced in the
>> setup.
>>>
>>> Now... to the point.
>>>
>>> When the user choses to close any particular MDI child form, from within
>> the
>>> form
>>>
>>> "Unload Me " is issued.
>>>
>>> Bottom line is that opening and closing the same form multiple times
>> results
>>> in more and more memory being allocated by VB and not being released. I
>> know
>>> that all variable references to the form should be set to Nothing, and
>>> any
>>> form controls referenced after the UNLOAD causes the form to be reloaded.
>>>
>>> Does VB allocate memory for every instance of a form object and retain
>> that
>>> memory "just in case" the form needs to be opened again? Even if we are
>>> setting all the references we can find to Nothing? Is there a simple way
>> to
>>> tell VB to release the memory?
>>>
>>> Thanks......
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>



Relevant Pages

  • Re: VB6 not releasing Memory when Form is Unloaded
    ... contents of Private form variables as you suggest. ... the major causes of memory usage in our project, ... > Public Sub Command1_Click ... > With the above example, after you close the form2 and unload it, if you ...
    (microsoft.public.vb.general.discussion)
  • RE: Before Save w Addin
    ... de-constructor for the form object (cleaning up memory and such). ... End Sub, then you can never be sure how much of the code executes. ... > Unload Userform1 ... I see nothing in the userform itself that causes me ...
    (microsoft.public.excel.programming)
  • Re: VB6 not releasing Memory when Form is Unloaded
    ... performance and memory usage. ... In addition, in your Form_Unload procedure, be sure to close the recordset, ... Private rs As New ADODB.RecordSet ... Private Sub Form_Load ...
    (microsoft.public.vb.general.discussion)
  • Re: Set object = nothing???
    ... > which is slower than memory. ... simpler) disconnect the recordset from the datasource. ... Private Sub Form_Click ... Dim NF As CField ...
    (microsoft.public.vb.general.discussion)
  • Re: VB6 not releasing Memory when Form is Unloaded
    ... value even if you use the command "Unload FormX" Example: ... Public Sub Command1_Click ... Private Sub Command1_Click ... Information about Form2 will always remain in memory, ...
    (microsoft.public.vb.general.discussion)