?
Solved

Fighting Memory Leaks

Posted on 2002-03-06
6
Medium Priority
?
227 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 400 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Introducing Priority Question

Increase expert visibility of your issues by participating in Priority Question, our latest feature for Premium and Team Account holders. Adjust the priority of your question to get emergent issues in front of subject-matter experts for help when you need it most.

Question has a verified solution.

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

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
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…
Suggested Courses

741 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