Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VBIDE and finding memory leaks

2 views
Skip to first unread message

Simon Woods

unread,
Oct 2, 2009, 4:41:32 AM10/2/09
to
Hi

I have a memory leak in my program which I'm trying to find.

I have the project open in the IDE and am stepping it with Task Manager
open and monitoring memory of the VB process. I was hoping see if there
was any obvious memory increase as I execute a chunk of code which
should clean itself up but doesn't. I've notice sometimes that as I step
over a call that the memory does increase, but I don't know for sure
whether it is my code or simply the effect of running it in the IDE. I'm
not suggesting that the IDE has memory leaks, only wondering whether
because it may be doing other things that it could give me false
positives for a possible culprit for where my memory leak may reside.

So is the IDE good enough for this or do I have to compile and
investigate this purely from binaries.

Thx

Simon

Ivar

unread,
Oct 2, 2009, 5:23:28 AM10/2/09
to
If it's GDI memory leeks that you are trying to find then a very useful
utility I use is here:
http://www.nirsoft.net/utils/gdi_handles.html
It wont find leaks (Can anything do that?) but by stepping through the code
in the VB IDE it will monitor how many of what type of GDI memory the IDE
and your app combined is using. That way you can see when new GDI memory is
being used and released by your app, from there you should be able to
determine where your app is not releasing memory. It worked for me!!
Hope this helps.

Ivar


"Simon Woods" <simon...@hotmail.com> wrote in message
news:%23rC$uwzQKH...@TK2MSFTNGP04.phx.gbl...

Simon Woods

unread,
Oct 2, 2009, 5:39:32 AM10/2/09
to
Thx Ivar, it is not actually GDI memory where my leak resides, but
nevertheless, the principle is the same, and from what you are saying,
it sounds like VB's IDE will not get in the way.

(I'll have a look at your link anyway ... always useful to know about
these things)

Thx again

Simon

Nobody

unread,
Oct 2, 2009, 12:31:27 PM10/2/09
to
If you are allocating global dynamic arrays, you need to use Erase statement
when you are done with them. You don't need it for arrays declared inside
procedures because VB automatically frees them. For module level variables
in forms, they are freed when Terminate event is called. This doesn't happen
when you use the predefined global variable that VB provides, such as Form1.
VB basically adds the following hidden code:

Public Form1 As New Form1

Many developers prefer to declare a variable of the form type. Here is an
example:

Public Sub ShowForm()
Dim f As Form1

Set f = New Form1

f.Show ' Show the form

' The following line doesn't unload the form. VB added an additional
' reference when the form is initialized(to use it to fire events) so
the
' form stays loaded. When the user closes the form, reference count
' reaches zero and both Unload and Terminate are called, freeing
' module level memory resources.
Set f = Nothing
End Sub

If the user opens and closes forms frequently, and you are using something
like Form1, then the memory resources used by the form are not freed. One
way to fix this is to add the following line of code as the last line in
Form_Unload:

Set <FormName> = Nothing

For Form1, this would be:

Set Form1 = Nothing

This causes Terminate to be called after Unload exits.

Also, the above applies to Strings except Erase statement, to free
global/module level strings, just assign "", or make sure that Terminate is
called for module level variables.

As for tools to watch memory usage, try searching the web for "VB profiler".

Finally, to print debugging messages from EXE's, use OutputDebugString(),
which prints a string to an external debug viewer. To view OutputDebugString
output, use this free software, which doesn't
require installation:

DebugView:
http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

Declaration:

Public Declare Sub OutputDebugString Lib "kernel32" Alias _
"OutputDebugStringA" (ByVal lpOutputString As String)

Usage:

OutputDebugString "ABC"

Wrapper sub:

Public Sub DebugPrint(ByRef s As String)
Debug.Print s
OutputDebugString s & vbCrLf
End Sub


Simon Woods

unread,
Oct 2, 2009, 1:04:46 PM10/2/09
to
On 02/10/2009 17:31, Nobody wrote:

<snip>

> As for tools to watch memory usage, try searching the web for "VB profiler".

I came across VB Watch ... but is that the one you had in mind?

Thx for your comments

Simon

Nobody

unread,
Oct 2, 2009, 1:26:54 PM10/2/09
to
"Simon Woods" <simon...@hotmail.com> wrote in message
news:u1tYCK4Q...@TK2MSFTNGP04.phx.gbl...

> I came across VB Watch ... but is that the one you had in mind?

I don't know if it shows memory usage, but you don't need it if all it does
is measure speed. Here is a free one to measure speed:

http://www.holmea.demon.co.uk/Profiler/Install.htm#EXE

Perhaps searching for "VB6 leak detector", "VB6 memory usage profiler"
provides better result...

http://www.google.com/search?hl=en&lr=&num=100&q=VB6+leak+detector
http://www.google.com/search?hl=en&lr=&num=100&q=VB6+memory+usage+profiler

"Visual Leak Detector" may show up in the result, but it's for C++ only.


Simon Woods

unread,
Oct 3, 2009, 5:07:50 AM10/3/09
to

Ok.... many thx again

Simon

Donald Lessau

unread,
Oct 3, 2009, 4:19:42 PM10/3/09
to
"Ivar" <ivar.eks...@ntlworld.com> schrieb im Newsbeitrag
news:kEjxm.328230$I35.1...@newsfe24.ams2...

> If it's GDI memory leeks that you are trying to find then a very useful
> utility I use is here:
> http://www.nirsoft.net/utils/gdi_handles.html
> It wont find leaks (Can anything do that?) but by stepping through the
> code in the VB IDE it will monitor how many of what type of GDI memory the
> IDE and your app combined is using. That way you can see when new GDI
> memory is being used and released by your app, from there you should be
> able to determine where your app is not releasing memory. It worked for
> me!!
> Hope this helps.
>
> Ivar

Interesting, thanks for the link. It told me that my app uses lots of Pens
although I don't ever use a pen in my code. But I have lots of PictureBoxes.
I assume the Pen is just part of the PictureBox. Is there any way to remove
the unused Pens from my app to free some unnecessary GDI handles?

Thanks,
Don

Mike Williams

unread,
Oct 4, 2009, 9:11:56 AM10/4/09
to
"Donald Lessau" <d...@oflex.com> wrote in message
news:uc9bWbGR...@TK2MSFTNGP04.phx.gbl...

> Interesting [the link posted by Ivar], thanks for the link.


> It told me that my app uses lots of Pens although I don't
> ever use a pen in my code. But I have lots of PictureBoxes. I assume the
> Pen is just part of the PictureBox. Is there
> any way to remove the unused Pens from my app to free
> some unnecessary GDI handles?

Each VB PictureBox initially has one DC associated with it, and that DC
contains references to various objects, including a pen and a bitmap.
However, most of them (including the bitmap) are references to stock
objects, or objects that already exist anyway whether the PictureBox is
there or not. The exception to this is the pen object, and each PictureBox
DC initially has its own pen associated with it even before you draw
anything into it. It is possible to delete the pens, but personally I don't
think it is advisable to mess about with the DCs of VB Controls, other than
on a temporary basis whilst you are doing something with them that you would
prefer to do using the various GDI functions. Leaving them in a state that
VB is not expecting can cause unexpected behaviour in certain circumstances.
Besides, VB will often delete some of thes epens itself, depending on what
you are doing.

Also, as soon as you start to draw things into the PictureBox it creates
other objects for itself if your drawing uses something other than the stock
objects it already has a reference to (a new pen for example, which it may
or may not hang on to depending on what you do afterwards, and a brush
perhaps depending on what you are drawing). A non-Autoredraw PictureBox does
not create a new bitmap though, because each PictureBox continues to
reference the appropriate portion of the same already existing bitmap that
would be there anyway, even if there were no PictureBoxes on your Form.
Additionally, if your PictureBox uses Autoredraw then it will create another
DC for itself the first time you attempt to draw something into it whilst
its Autoredraw property is True, and it will create a new bitmap object to
go into it. That DC will also initially contain references to existing stock
items unless the thing you are drawing requires a different item (a
different colour pen or something) in which case it will behave exactly the
same as in the previous case. Personally if I were you I would advise you to
leave this system alone, and allow VB to do whatever it wishes, only
altering things (if really necessary) on a purely temporary basis whilst you
perhaps do somehting in it that you would prefer to do using GDI functions.

All of the above are the initial conditions when you do only the few things
described. As you begin to do various things in the various PictureBoxes the
total number of pens and other objects associated with them may increase or
may decrease, depending on what you are doing, and in many cases you can end
up with less pens than your started with. The best thing is to leave all
this behaviour to VB and not try to mess with it. If you want more control
over the resources allocated and if you have lots and lots of PictureBoxes
then you really should consider getting rid of them altogether, or at least
getting rid of a lot of them, and creating and using your own resources
using GDI functions. Perhaps if you tell us what you are doing with all
these PictureBoxes we may be able to give you more specific advice. It is
possible that you can continue to perform the same job you are doing, and
continue to use standard VB methods to do so, without any PictureBoxes at
all, or at least with a lot less of them. The more detail you give, the
better. A detailed description of the job you are doing would be better than
a description of the methods you are currently using to do it.

Mike


Donald Lessau

unread,
Oct 4, 2009, 2:08:59 PM10/4/09
to

"Mike Williams" <Mi...@WhiskyAndCoke.com> schrieb im Newsbeitrag
news:%23meH%23QPRK...@TK2MSFTNGP04.phx.gbl...

Thanks, Mike. In my case it would be a lot of work to replace the
comfortable PictureBoxes with some "owner-created DCs" (I mostly just need
the hDC for blitting and text, and the hWnd for size and position). I wonder
whether the effort would be worth it. After all, what is a pen? The LOGPEN
Structure has about 12 bytes (?), so when I have 100 pens, who cares. Or is
there some limit as to the number of pens or GDI handles in general?

Don

Schmidt

unread,
Oct 4, 2009, 2:53:43 PM10/4/09
to

"Donald Lessau" <d...@oflex.com> schrieb im Newsbeitrag
news:uc9bWbGR...@TK2MSFTNGP04.phx.gbl...

> Interesting, thanks for the link. It told me that my app uses
> lots of Pens although I don't ever use a pen in my code.
> But I have lots of PictureBoxes.
> I assume the Pen is just part of the PictureBox. Is there
> any way to remove the unused Pens from my app to free
> some unnecessary GDI handles?

Yes, set the .DrawStyle-Property from 0 (the default)
to 5 (transparent).

By default each Form and each PicBox (and also each
VB-Usercontrol) is wasting such a Pen-Handle.

Easy to check-up in the TaskManager (once you know,
what setting to change) - but wasn't all that easy to find
which was causing this (digged that out some years ago,
as I tried to write my first set of windowless Controls -
always wondering, why on earth these "damned things"
took up GDI-resources altough I tried to avoid exactly
that in my code - until I started playing with the settings
on all these "Drawing-Props" (step by step).

Olaf

Donald Lessau

unread,
Oct 4, 2009, 3:40:34 PM10/4/09
to
"Schmidt" <s...@online.de> schrieb im Newsbeitrag
news:Oq3O4TSR...@TK2MSFTNGP04.phx.gbl...

Wow, this was more like the kind of answer I vaguely hoped to get. :D
So "transparent" is a funny way to say "none", tz tz tz.

Thanks for digging that one out,
Don

Mike Williams

unread,
Oct 4, 2009, 4:34:36 PM10/4/09
to
"Donald Lessau" <d...@oflex.com> wrote in message
news:eajQN3R...@TK2MSFTNGP02.phx.gbl...

> Thanks, Mike. In my case it would be a lot of work to replace the
> comfortable PictureBoxes with some "owner-created DCs" (I mostly
> just need the hDC for blitting and text, and the hWnd for size and

> position). After all, what is a pen? The LOGPEN Structure has


> about 12 bytes (?), so when I have 100 pens, who cares.

Well apparently you do, because you didn't tell us until just now how many
you had, but you did ask how you could get rid of them :-) Anyway, I see
you've now had a suggestion from Olaf to set the PictureBox DrawStyle to
Transparent, which removes the otherwise unused pen. Good idea that . . . I
didn't know about that one myself :-(

> Or is there some limit as to the number of pens or
> GDI handles in general?

Yes, there is a limit on the amount of GDI handles you can have, regardless
of how little memory they may take up or how much memory you've got. There
is an overall limit and also a limit per process:

http://msdn.microsoft.com/en-us/library/ms724291(VS.85).aspx

Mike


0 new messages