LoadResPicture = Out of Memory in VB6

Good day

I've got a very large VB6 application +-40 000 lines of code and in the application I have a module that look something like this to load my pictures, cursors etc.:

Option Explicit

Public Property Get Resources_UnCheck() As IPictureDisp
  Set Resources_UnCheck = LoadResPicture("UNCHECK", vbResBitmap)
End Property

Public Property Get Resources_Check() As IPictureDisp
  Set Resources_Check = LoadResPicture("CHECK", vbResBitmap)
End Property

Public Property Get Resources_DownArrow() As IPictureDisp
  Set Resources_DownArrow = LoadResPicture("DOWN_ARROW", vbResCursor)
End Property

Public Property Get Resources_Hand() As IPictureDisp
  Set Resources_Hand = LoadResPicture("HAND", vbResCursor)
End Property

Public Property Get Resources_Aanvaar_Large() As IPictureDisp
  Set Resources_Aanvaar_Large = LoadResPicture("AANVAAR_LARGE", vbResBitmap)
End Property

Public Property Get Resources_Cancel_Large() As IPictureDisp
  Set Resources_Cancel_Large = LoadResPicture("CANCEL_LARGE", vbResBitmap)
End Property

Public Property Get Resources_Gradient_Grid_Headers() As IPictureDisp
  Set Resources_Gradient_Grid_Headers = LoadResPicture("GRID_HEADER", vbResBitmap)
End Property

Public Property Get Resources_Lock() As IPictureDisp
  Set Resources_Lock = LoadResPicture("LOCK", vbResBitmap)
End Property

Public Property Get Resources_Image_ByName(ByVal sName As String) As IPictureDisp
  sName = Replace(sName, "LST_DROOG_KOEI", "LST_DROOG")
  Set Resources_Image_ByName = LoadResPicture(sName, vbResBitmap)
End Property

Public Property Get Resources_Animal_Water_Mark(ByVal bLeft As Boolean) As IPictureDisp
  If bLeft = False Then
    Set Resources_Animal_Water_Mark = LoadResPicture("BEESWMRIGHT", vbResBitmap)
  Else
    Set Resources_Animal_Water_Mark = LoadResPicture("BEESWMLEFT", vbResBitmap)
  End If
End Property

Open in new window


Then in the software I do set a couple of pictures for picture boxes, .CellPicture  for mshflexgrid and IPictureDisp variables to some of these resources.

My application starts to give me Out of memory errors.

If I comment out the resource file I do not get the out of memory anymore.  Any idea how I can change my code to prevent this from happening?

koossaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Martin LissOlder than dirtCommented:
What do you mean when you say you "comment out the resource file"? Do you mean that you comment out the lines of code that you show above?

At what point does the error happen? Immediately or after you LoadResPicture a few times?


-------------------------------------------------------------------------------------------------------------------------------
My Articles:
Using the VB6 DebuggerAutomatic Insertion of Procedure Names
A Textbox ActiveX Control That Limits Input to NumbersSpell Check a Textbox
Improved Formatting TagsConditional Compilation

Marty - MVP 2009, 2010, 2011
0
koossaAuthor Commented:
By commenting out I mean this
Option Explicit

Public Property Get Resources_UnCheck() As IPictureDisp
  Set Resources_UnCheck = Nothing 'LoadResPicture("UNCHECK", vbResBitmap)
End Property

Public Property Get Resources_Check() As IPictureDisp
  Set Resources_Check = Nothing 'LoadResPicture("CHECK", vbResBitmap)
End Property

Public Property Get Resources_DownArrow() As IPictureDisp
  Set Resources_DownArrow =Nothing  'LoadResPicture("DOWN_ARROW", vbResCursor)
End Property

Public Property Get Resources_Hand() As IPictureDisp
  Set Resources_Hand = Nothing  'LoadResPicture("HAND", vbResCursor)
End Property

Public Property Get Resources_Aanvaar_Large() As IPictureDisp
  Set Resources_Aanvaar_Large =Nothing  'LoadResPicture("AANVAAR_LARGE", vbResBitmap)
End Property

Public Property Get Resources_Cancel_Large() As IPictureDisp
  Set Resources_Cancel_Large =Nothing  'LoadResPicture("CANCEL_LARGE", vbResBitmap)
End Property

Public Property Get Resources_Gradient_Grid_Headers() As IPictureDisp
  Set Resources_Gradient_Grid_Headers =Nothing  'LoadResPicture("GRID_HEADER", vbResBitmap)
End Property

Public Property Get Resources_Lock() As IPictureDisp
  Set Resources_Lock =Nothing  'LoadResPicture("LOCK", vbResBitmap)
End Property

Public Property Get Resources_Image_ByName(ByVal sName As String) As IPictureDisp
  sName = Replace(sName, "LST_DROOG_KOEI", "LST_DROOG")
  Set Resources_Image_ByName =Nothing  'LoadResPicture(sName, vbResBitmap)
End Property

Public Property Get Resources_Animal_Water_Mark(ByVal bLeft As Boolean) As IPictureDisp
  If bLeft = False Then
    Set Resources_Animal_Water_Mark =Nothing  'LoadResPicture("BEESWMRIGHT", vbResBitmap)
  Else
    Set Resources_Animal_Water_Mark =Nothing  'LoadResPicture("BEESWMLEFT", vbResBitmap)
  End If
End Property

Open in new window



It gives me an error after loading 8 718 rousources from this module.

0
Martin LissOlder than dirtCommented:
Do you need to have 8718 resources loaded all at once? Could you create a Public Property Set for each one that sets them to Nothing after you have used them?

0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

koossaAuthor Commented:
No, its not all at once, I open and close about 10 forms and do a count on each resource load and that adds up to 8 718 executions of the LoadResPicture function.
0
Martin LissOlder than dirtCommented:
Try setting your forms to Nothing after you Unload them.
0
koossaAuthor Commented:
I've call a function when I click on a button to load the new form
Call ShowRelativeToFormMain(frmRegistrasie)

Open in new window



And then in the function I set the form to nothing, but it still gives me an out of memory.

Public Sub ShowRelativeToFormMain(ByRef MyForm As Form)
  Dim iShow As FormShowConstants
  If IsFormLoaded("frmMain") = True Then
    MyForm.Show vbModal, frmMain
  Else
    MyForm.Show vbModal
  End If
  DoEvents
  Set MyForm = Nothing
End Sub

Open in new window

0
Martin LissOlder than dirtCommented:
Sorry but the only other thing I can suggest is that you look at the 'Performance' tab in Windows taskManager and see if memory usage drops when you close a form.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
koossaAuthor Commented:
When I monitor the VB.exe's memory usage in task manager I see the following by running my software and only open and close the same form.


Before running my app 20.8MB
Run it : 38.9MB
Open Form 1 : 41.9MB
Close Form 1 : 40.9MB
Open Form 1 : 43.5MB
Close Form 1 : 43.1MB
Open Form 1 : 44.7MB
Close Form 1 : 44.1MB
Stop my software : 44.5MB


Even when I stop my software in VB, it does not release the memory.
0
Martin LissOlder than dirtCommented:
Look in Task Manager 'Processes'. Do you see any VB6.EXE?
Look in 'Applications' Is you app running?
0
koossaAuthor Commented:
Yes, VB.exe is in Processes and in Applications, my app is running, and when I stop it, it disappeared from applications, but in processes the VB.exe's memory usage is still 44.5MB.
0
Martin LissOlder than dirtCommented:
0
koossaAuthor Commented:
How do I analyse the log file, I don't understand what to look for?

Created by MemoryHooks
----------------------
Dumping leaks from 10 heaviest stacks

------------------------------------------------

Stack #1, total leak size: 64
	call stack:
		0x7c9114d6 --> [ntdll] RtlDeleteCriticalSection
		0x7c911566 --> [ntdll] RtlInitializeCriticalSectionAndSpinCount
		0x7c91162c --> [ntdll] RtlInitializeCriticalSection
		0x7c809f9f --> [kernel32] InitializeCriticalSection
		0x765b9759 --> [MSDART] CReaderWriterLock3::ReadOrWriteLock
		0x765b947c --> [MSDART] MPInitializeCriticalSection
		0x60e37d31 --> [MSDATL3] CBaseObj::CBaseObj
		0x4dd0e9e0 --> [SQLOLEDB] 
		0x4dd2390b --> [SQLOLEDB] DllMain
		0x4dd2395e --> [SQLOLEDB] DllMain
		0x4dd23893 --> [SQLOLEDB] DllMain
		0x7407be50 --> [msadce] DllGetClassObject
		0x74070b9f --> [msadce] DllGetClassObject
		0x7406eca1 --> [msadce] DllCanUnloadNow
		0x7406f576 --> [msadce] DllCanUnloadNow
		0x7406f5b6 --> [msadce] DllCanUnloadNow
		0x740963db --> [msadce] 
		0x74096512 --> [msadce] 
		0x4de1cb13 --> [msado15] DllGetClassObject
		0x4de3ab0e --> [msado15] DllCanUnloadNow
		0x4de1ca21 --> [msado15] DllGetClassObject
		0x4de1c92a --> [msado15] DllGetClassObject
		0x4de1c642 --> [msado15] DllGetClassObject
		0x4de16223 --> [msado15] 
		0x4de1603d --> [msado15] 
		0x0fc00e3a --> [VBA6] ProcCallEngine
		0x0fc00db5 --> [VBA6] ProcCallEngine
		0x0fc00db5 --> [VBA6] ProcCallEngine
		0x0fc00dfd --> [VBA6] ProcCallEngine
		0x77135cd9 --> [OLEAUT32] DispCallFunc
		0x0fa96a9b --> [VBA6] EbFinishHostEvent
		0x0fa96799 --> [VBA6] EbFinishHostEvent
		0x0049028d --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0fa9475c --> [VBA6] rtcAnsiValueBstr
		0x0fc0319e --> [VBA6] MethCallEngine
		0x0fc03116 --> [VBA6] MethCallEngine
		0x0fc035e2 --> [VBA6] MethCallEngine
		0x0fc001e9 --> [VBA6] ProcCallEngine
		0x0fc00d67 --> [VBA6] ProcCallEngine
		0x004841cd --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x042e2de8 --> [VB6] 
		0x004841a6 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0049092a --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x004907e3 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0fb48673 --> [VBA6] TestGetModCompState
		0x0fc08b71 --> [VBA6] 
		0x0fc00dfd --> [VBA6] ProcCallEngine
		0x0fc00dfd --> [VBA6] ProcCallEngine
		0x77135cd9 --> [OLEAUT32] DispCallFunc
		0x0fa96a9b --> [VBA6] EbFinishHostEvent
		0x0fa96799 --> [VBA6] EbFinishHostEvent
		0x0049028d --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0fa9475c --> [VBA6] rtcAnsiValueBstr
		0x0fc03292 --> [VBA6] MethCallEngine
		0x0fc000e4 --> [VBA6] ProcCallEngine
		0x0fc00d67 --> [VBA6] ProcCallEngine
		0x0fc00e3a --> [VBA6] ProcCallEngine
		0x0fc00d67 --> [VBA6] ProcCallEngine
		0x004841cd --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x034f7f94 --> [VB6] 
		0x004841a6 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0049092a --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x004907e3 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0fb48673 --> [VBA6] TestGetModCompState
		0x0fc08b71 --> [VBA6] 
		0x0fc00dfd --> [VBA6] ProcCallEngine
		0x004841cd --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x03593bdc --> [VB6] 
		0x004841a6 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0047d8c6 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0047d738 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x00490f67 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0047c32a --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x00471dab --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0047aeda --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0047d660 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x0047cff8 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x7e418734 --> [USER32] GetDC
		0x7e418816 --> [USER32] GetDC
		0x7e4189cd --> [USER32] GetWindowLongW
		0x7e4196c7 --> [USER32] DispatchMessageA
		0x004828f2 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x00482852 --> [VB6] VB_CALLBACK_GETHWNDMAIN_
		0x3078d224 --> [MSO97RT] MsoBcacheLimit
		0x306c3498 --> [MSO97RT] MsoFCreateStdComponentManager
		0x0824448b --> [MSO97RT] 

Allocation size = 32:...s...X...
Allocation size = 32:...`... . . . .
------------------------------------------------

Stack #2, total leak size: 28
	call stack:
		0x774fd2aa --> [ole32] CoTaskMemAlloc
		0x77505a88 --> [ole32] CreateStreamOnHGlobal
		0x77505a4c --> [ole32] CreateStreamOnHGlobal
		0x74086bac --> [msadce] DllGetClassObject
		0x74093cfc --> [msadce] 
		0x4de660a5 --> [msado15] com_ms_wfc_data_Field_getDataTimestamp
		0x4de66235 --> [msado15] com_ms_wfc_data_Field_getDataTimestamp
		0x4de3feee --> [msado15] DllCanUnloadNow
		0x4de151f2 --> [msado15] 
		0x4de15adb --> [msado15] 
		0x4de1cfc2 --> [msado15] DllGetClassObject
		0x4de1ca21 --> [msado15] DllGetClassObject
		0x4de1c92a --> [msado15] DllGetClassObject
		0x4de1c642 --> [msado15] DllGetClassObject
		0x4de16223 --> [msado15] 
		0x4de1603d --> [msado15] 
		0x24e75e67 --> [MSADODC] DLLGetDocumentation
		0x24e75bbc --> [MSADODC] DLLGetDocumentation
		0x24e75588 --> [MSADODC] DLLGetDocumentation
		0x0778247c --> [MSADODC] 
		0x24e72fb4 --> [MSADODC] DLLGetDocumentation
		0x00000020 --> [MSADODC] 

Allocation size = 28:..NwSTRM...L...w.x3w.
------------------------------------------------

Stack #3, total leak size: 32
	call stack:
		0x7c9114d6 --> [ntdll] RtlDeleteCriticalSection
		0x7c911566 --> [ntdll] RtlInitializeCriticalSectionAndSpinCount
		0x7c91162c --> [ntdll] RtlInitializeCriticalSection
		0x7c809f9f --> [kernel32] InitializeCriticalSection
		0x765b9759 --> [MSDART] CReaderWriterLock3::ReadOrWriteLock
		0x765b947c --> [MSDART] MPInitializeCriticalSection
		0x7406fc24 --> [msadce] DllGetClassObject
		0x7407000b --> [msadce] DllGetClassObject
		0x740701a0 --> [msadce] DllGetClassObject
		0x7407017a --> [msadce] DllGetClassObject
		0x774ff267 --> [ole32] CoCreateInstance
		0x774ff109 --> [ole32] CreateBindCtx
		0x774ff1a3 --> [ole32] CoCreateInstanceEx
		0x774ff172 --> [ole32] CoCreateInstanceEx
		0x774ff1e0 --> [ole32] CoCreateInstance
		0x4de4126b --> [msado15] DllCanUnloadNow
		0x4de36a74 --> [msado15] DllCanUnloadNow
		0x4de3ab0e --> [msado15] DllCanUnloadNow
		0x4de1ca21 --> [msado15] DllGetClassObject
		0x4de1c92a --> [msado15] DllGetClassObject
		0x4de1c642 --> [msado15] DllGetClassObject
		0x4de16223 --> [msado15] 
		0x4de1603d --> [msado15] 
		0x24e75e67 --> [MSADODC] DLLGetDocumentation
		0x24e75bbc --> [MSADODC] DLLGetDocumentation
		0x24e75588 --> [MSADODC] DLLGetDocumentation
		0x043ea814 --> [MSADODC] 
		0x24e72fb4 --> [MSADODC] DLLGetDocumentation
		0x00000020 --> [MSADODC] 

Allocation size = 32:...$... *a...D...:...
------------------------------------------------

Stack #4, total leak size: 622864
	call stack:
		0x765b9067 --> [MSDART] MpHeapAlloc
		0x765b9039 --> [MSDART] MpHeapAlloc
		0x7406192e --> [msadce] 
		0x7406195c --> [msadce] 
		0x740689ce --> [msadce] 
		0x740670de --> [msadce] 
		0x74067049 --> [msadce] 
		0x74066e8c --> [msadce] 
		0x74067151 --> [msadce] 
		0x740945a9 --> [msadce] 
		0x74067695 --> [msadce] 
		0x74069f06 --> [msadce] 
		0x74069e7b --> [msadce] 
		0x740963f3 --> [msadce] 
		0x74096512 --> [msadce] 
		0x4de1cb13 --> [msado15] DllGetClassObject
		0x4de3ab0e --> [msado15] DllCanUnloadNow
		0x4de1ca21 --> [msado15] DllGetClassObject
		0x4de1c92a --> [msado15] DllGetClassObject
		0x4de1c642 --> [msado15] DllGetClassObject
		0x4de16223 --> [msado15] 
		0x4de1603d --> [msado15] 
		0x24e75e67 --> [MSADODC] DLLGetDocumentation
		0x24e75bbc --> [MSADODC] DLLGetDocumentation
		0x24e75588 --> [MSADODC] DLLGetDocumentation
		0x0776bccc --> [MSADODC] 
		0x24e72fb4 --> [MSADODC] DLLGetDocumentation
		0x00000020 --> [MSADODC] 

Allocation size = 32776:

Open in new window

0
Martin LissOlder than dirtCommented:
I'm sorry but I don't know either. I just saw the tool on the web and I thought it might help.
0
Martin LissOlder than dirtCommented:
What does your IsFormLoaded function look like?
0
koossaAuthor Commented:
Public Function IsFormLoaded(ByVal sFrmName As String) As Boolean
  Dim MyForm As Form
  For Each MyForm In Forms
    If LCase$(MyForm.Name) = LCase$(sFrmName) Then
      IsFormLoaded = True
      Exit For
    End If
  Next
End Function

Open in new window

0
koossaAuthor Commented:
Did not solve my problem, but direct me into the right direction.
0
Martin LissOlder than dirtCommented:
I'm glad I was able to help. What was the problem?
0
koossaAuthor Commented:
I think it is the ADODC data control that is part of one of my custom usercontrols that somehow does not release from memory.  I have tried the following without any luck, but will get to the root of it.
It seems like the custom control's terminate event does not get fired when I unload a form and in that event I close the datacontrol.

  Set DataControl.Recordset = Nothing
  DataControl.ConnectionString = ""
  DataControl.RecordSource = ""
  Set Grid.DataSource = Nothing

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.