tags:

views:

811

answers:

4

The proper way to end a vb6 program is to do something like this :

Dim frm As Form
   For Each frm In Forms 
       Unload frm
   Next frm
   end

That takes care of forms, what takes care of modules in memory?

+3  A: 

Don't use End, you don't need to (ever). Then all memory gets freed properly.

Even using End, memory should be freed automatically. There was a rumor that some class instances are forgotten and don't get terminated correctly, despite reference counting. Thus, it's been established as best practice to set all object instances to Nothing explicitly (especially, but not limited to instances allocated in modules). I've never seen any confirmation that this is actually true (it might still be, though!).

Konrad Rudolph
OK that's interesting, thanks for explaining the reason why using end doesn't work
kjack
I had a web app a while ago with some vb6 backend dlls, and it leaked like a sieve until I explicitly cleaned up all my objects. Even then it wasn't perfect. A real eye opener.
johnc
-1 Circular references have to be explictly handled. This can occur in a complex VB6. If a circular reference is not handled then the application will APPEAR to shut down however still remain as a process chewing up resources.End is a holdover for compatibility from VB 1.X to 3.X.
RS Conley
RS: Yes, circular references are a special case which I didn't mention (perhaps wrongly) for simplicity. Yes, I probably should have.
Konrad Rudolph
The application will only continue if the main form is participating in the circular reference. Otherwise, circular references will get cleaned up on shut down.
Darrel Miller
And still, even circular references will *NOT* prevent a program from shutting down. That's nonsense. Anyway, there are some well-published solutions (using weak references) to combat circular references. Not very clean, but robust if done right. No `End` necessary.
Konrad Rudolph
Darrel: oops, didn't see you already saying this. I forgot to submit the comment yesterday evening (Europe …) and did it this morning.
Konrad Rudolph
+4  A: 

There is no need to explicitly unload modules in VB6. They are unloaded automatically when the last form is unloaded. The language doesn't support references to standard modules at all, only to the (global) functions and variables defined therein. Since you can't reference the module, you can't unload them either.

JeffK
OK accepting this as it answers the question. Can you tell me though if End will unload all modules even if say a form was still loaded?
kjack
No, End will not unload the modules. It's a pity that MS even has the End statement. It will most likely leave the unloaded forms in memory, creating a memory leak.
HardCode
Harcode is wrong. The End statement does unload all forms, objects, etc. But End is considered "Evil" by most VB6 programmers. It does not fire the Unload or QueryUnload or Terminate events of forms or class modules. The VB help says it should not be used for normal termination of a VB program.
MarkJ
End kills the application as it is, without calling destructors or cleaning anything up. Windows then frees the memory and open handles associated with the process and I think orphans out-of-process COM objects. Avoid wherever possible.
rpetrich
Bruce McKinney, in Hardcore Visual Basic, described the "End" statement as "ripping your program out of memory," leaving Windows to clean up after your mess. You should track your forms cleanly, and release them when you're done. Modules are handled by the VB runtime once that last form is gone...
JeffK
Continued: The "For Each frm In Forms" loop in the original question is a way to do half the job. While all forms are released, it's a bit sloppy, and indicates you're not really tracking the forms you create. Maybe it's covering up a memory leak, where you've lost track of created forms.
JeffK
+1  A: 

Note that if you use global variables then you should check if any of them need to get cleaned up. If so you should have a CleanUp method of your module and call that during the unload event of your main form. Another gotcha is sometimes the ORDER of how you unload things is important. By doing an explicit cleanup you can control that.

In VB6 you should rarely use END. If you have any circular references the program will remain as a process chewing up resource causing various strange bugs when you fire it up again. With COM objects is very easy to in inadvertently setup a chain of object thats is circularly linked.

End exists as a compatibility holdover from previous version of QuickBASIC and Visual BASIC. It did not start causing major problems until VB 4.X introduced the ability to create classes. It started gaining attention in 5.X.

Prior to this one of the only ways to make this happen in VB 3.X is to have two forms set references to each other.

RS Conley
This global variable problem only applies to object variables of class modules, not to data types found in ordinary .bas modules, right?
kjack
"the program will remain as a process chewing up resource causing various strange bugs when you fire it up again." But won't it be in a different process and thereby unable to interfere with the new instance?
kjack
Point #1. If you are using UDTs or simple data types then there is no problem.
RS Conley
Point #2. This depends on the settings of your ActiveX (COM) DLL. Remember COM was designed in a era where conserving memory was important. So you can have a ActiveX DLL open that is shared by all running applications.
RS Conley
However practically this really only has an impact if you are using some external resource. XP and Vista are pretty good at keeping COM DLLs from stomping over each other.
RS Conley
OK I think I understand, thanks
kjack
+1  A: 

If by "module" you mean static .BAS modules (they're all modules: Forms, Classes, UserControls, etc.) you don't need to "unload" them because they're static.

Most other module types are dynamically loaded. In the case of Forms typically via the predeclared global reference variable with the same name and type as the Form class (yes, a Form is a kind of class).

Bob
Could you explain static in this context? I mean I understand what a static variable is
kjack
Such modules are static in the sense that their code and data are loaded as long as the program is running, and there is no way to create multiple instances of the data.
Bob