• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 230
  • Last Modified:

Fighting Memory Leaks

    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?
  • 3
  • 2
1 Solution
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.

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.
GebhartBobAuthor Commented:
    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.
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

>Prudence ... destroy ... objects ...


>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
GebhartBobAuthor Commented:
    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.
Glad to help...
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now