Solved

Fighting Memory Leaks

Posted on 2002-03-06
6
220 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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

746 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now