Solved

Fighting Memory Leaks

Posted on 2002-03-06
6
222 Views
Last Modified: 2010-05-02
    Each time I run our VB app, I can see available physical memory dropping. My problem is that I don't have any experience with combatting VB memory leaks. I could sure use some words of wisdom on general technique.
 
     I presume I have caused the problem by allocating memory for objects (like forms) which I don't release.
 
     For example, I keep several copies of some forms loaded but not shown, so that response is very quick. It works just fine, but I suspect is the cause of at least some of my memory problems.
 
     I have an array of forms, like so:
 
Private FormsArray(100) As Form
 
     When I need to create a form, I do this:

Set FormsArray(Index) = New frmXXX
Load FormsArray(Index)
 
     When I'm done with the form, all I do is Unload it. That's probably where I'm going wrong. I probably ought to do this:
 
Unload FormsArray(Index)
Set FormsArray(Index) = Nothing
 
     In general, when looking for a memory leak, I should find all "New's" and make sure I eventually set those variables to "Nothing".
 
     That's a question, not an assertion. What else should I look for?
0
Comment
Question by:GebhartBob
  • 3
  • 2
6 Comments
 
LVL 5

Expert Comment

by:rpai
ID: 6845320
1. All the objects that have been instanciated either with New/CreateObject/CreateInstance keywords, all need to be set to Nothing to release the memory.

2. All arrays need to be erased to release the memory using the keyword ERASE.
For instance:-
Dim iArr(5) as Variant
.
.
Erase iArr

3. In case of errors, all the objects need to be closed as well. So in all the error handlers of your code, Step 1 and Step 2 need to be carried out.

Hope this is informative.

Cheers!
0
 
LVL 22

Accepted Solution

by:
rspahitz earned 100 total points
ID: 6845400
You seem to be on the right track (Set=nothing)

In my experience, VB6 is pretty good about cleaning up after the programmer, but it's still possible for something to get "stuck" especially if you have a connection to a database open somewhere.

In general, whenever you make and object, you should destroy the object.  However, sometimes it's not obvious.  This is where getting to know the system really helps.

For example,

' Allocate space for SomeObject
Dim obj as SomeObject

' Actually make the object
Set obj = New SomeObject

' Do something with the object

' Clear the object
Set obj = Nothing

--
The difficulty comes in that different objects may work differently.  For example, if you "show" a form, it gets instantiated (automatically), then loaded (automatically), then show.  So to get rid of the form, you must unload, then terminate (set = nothing.)  Normally this is done automatically when you unload your main form.

Another example is that if you reference a control on a form (to get, maybe, the font size such as AnotherForm.font.size = PreviouslyUnaccessedForm.Text1.Font.size) it will instantiate it, then load it, then get the information.  The form is now sitting around, hidden, but tying up memory...and will usually go away when the main form unloads.

If a form_load contains a connection to a database or some other object outside of the application, that connection will not be broken unless you force it to disconnect, which can be done by either closing the connection or (sometimes) unloading the form that references it.
0
 

Author Comment

by:GebhartBob
ID: 6845543
    I forgot to mention something that's probably obvious from my original question, but our application is MDI, with multiple copies of some child forms. We manage those multiple copies, to significantly improve response time.
 
     I get the impression that unloading a form ought to deallocate all memory associated with that form (which seems reasonable to me), but sometimes it doesn't do its thing properly. Prudence dictates that you should explicitly destroy all of the objects you create, right?
 
     If in a Sub I Dim an array, or create an object of some kind, that array or object is NOT automagically destroyed when I exit the Sub?
 
     I'm just trying to get me feet on the ground here. Thanks very much for your help.
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 22

Expert Comment

by:rspahitz
ID: 6845586
>Prudence ... destroy ... objects ...

Yes.


>that array or object is NOT automagically destroyed when I exit the Sub?

Well, it depends partly on scope and partly on how it's created.  Generally, any variable or object defined and created within a procedure will be destroyed when the procedure completes (unless you use Static.)  Likewise, and variable or objcet defined at the module level (including form modules) will usually be destroyed then the form "completes" (i.e. "is destroyed".)  Anything defined at the global level will obviously stick around for the life of the application.

Again, the except seems to be things that are bound to other things outside of the scope, such as database connections.

In your case, with MDI forms, I suspect that you simply have some hidden forms that are never being destroyed, and I guess the MDI unload procedure is not unsuring that they go away.

Why not try this:

Private Sub MDIForm_Unload()
  dim ctlForm as Form

  for each ctlForm in Forms
    if ctlForm.name <> Me.Name then
      unload ctlForm
    end if
  next ctlForm
end sub
0
 

Author Comment

by:GebhartBob
ID: 6845650
    Well, I'm a long way from complete understanding, but at least you've given me a good push in the right direction, which is all I could have hoped for.
 
     Thanks for your very lucid comments, and for the time they took.
0
 
LVL 22

Expert Comment

by:rspahitz
ID: 6845669
Glad to help...
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question