Solved

VB6 LoadPicture memory leak?

Posted on 2004-09-09
17
3,248 Views
Last Modified: 2008-01-09
Hi everybody,

This is a tough one, but maybe someone out there knows the answer. Basically, I have a piece of code which reads in a multi-page TIFF file, then loops through each page, shrinking it and saving to a bitmap file, then loading that bitmap file back in via a call to LoadPicture and saving it to the IPictureDisp property of a thumbnail object I created. However, it seems that there's a memory leak associated with LoadPicture, because on anywhere between page 1000 and page 1400, I get an error #7, out of memory error, and it always occurs on the call to LoadPicture. My code calling LoadPicture is:

                Set picTempPicture = LoadPicture()
                Set picTempPicture = LoadPicture(strThumbnailBMP)
                objThumb.ThumbnailImage = picTempPicture

I put in the call to LoadPicture() in the vain hopes that it would clear out the memory on each loop, but no such luck. I also split the assignment of objThumb.ThumbnailImage to LoadPicture into separate lines so as to verify that the out of memory error was occurring on LoadPicture and not on the assignment to objThumb.ThumbnailImage.

Does anyone have any knowledge of such a problem and how it can be fixed? I'm really stumped on this one, and searching on Google for LoadPicture and "out of memory" has come up dry. 500 points for this one...

Regards,
William W. Lin
wlin@cobius.com
0
Comment
Question by:billin
  • 6
  • 5
  • 2
  • +2
17 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 12015901
Out of memory error on the LoadPicture line means that this line needs a large amount of memory, which is not available now.
Line causes memory leak if it runs in the loop and memory consumed by the program is constantly grows. These are two different things (while they may be true for the same program line).
However, there is another line here:

objThumb.ThumbnailImage = picTempPicture

What is objThumb? If all images loaded by LoadPicture are kept somewhere without being released, Out of memory error may appear.
0
 
LVL 32

Expert Comment

by:Erick37
ID: 12016208
Shouldn't the line be:
Set picTempPicture = LoadPicture("") '<< Note the quotes
0
 

Author Comment

by:billin
ID: 12016531
Hi Alex - objThumb is of class ScanThumbnail, which I created, and the .ThumbnailImage property is of type IPictureDisp (i.e. the return type of LoadPicture). The odd thing about this memory leak is that the system memory is nowhere near full - only about 40% total usage - when the program crashes with an out of memory error. As for the images loaded by LoadPicture not being released, I am, indeed, storing each LoadPicture image to a separate thumbnail, but why should it crash after 1000 thumbnails? Shouldn't the program just expand its memory footprint to meet the added memory requirements?

Hi Erick37 - no, LoadPicture should not have quotes, as the arguments are Optional. If no arguments are supplied, the function clears out the image as described here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vb98/html/vbfctloadpicture.asp
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 12016692
A long shot:

Try...

    Set picTempPicture = LoadPicture(strThumbnailBMP)
    objThumb.ThumbnailImage = picTempPicture
    Set picTempPicture = Nothing

0
 
LVL 5

Expert Comment

by:NashvilleGuitarPicker
ID: 12020704
If you modify your code to not reload the thumbnails (just convert them), does it still run out of memory?  If so, then the memory leak may be occurring in that module, and .

Another possibility is that your stack memory is full.  There are some memory limitations in VB.  The following thread discusses similar problems:

http://www.mail-archive.com/pro_vb@p2p.wrox.com/msg05210.html

What OS is this running on?

- Will
0
 

Author Comment

by:billin
ID: 12027817
Hi Idle_Mind - thanks for the suggestion, but no dice - it still crashes...

Hi Will - it's a VB6 app running on Windows XP. You bring up an interesting possibility re: stack memory. However, it doesn't seem like stack memory, because the memory leaked is persistent across calls to this function. That is, I can call this function once with 500 pages, and it'll be fine. Then when I call it again later on down the line with another 500 pages, it'll crash on the 1000th page, having reached the total threshold of 1000 pages (this is not exact - the limit actually varies between 1000 and 1400 pages). On the other hand, I can simply call the function with 1000 pages, and it'll crash on the 1000th page (again, not exact). Plus, aren't objects (i.e. Set obj = ...) allocated on the heap? I'm not sure...

Any other ideas?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 12027911
One thing that hasn't been really addressed is your class that you created:

   objThumb.ThumbnailImage = picTempPicture

How are you storing the thumbnails in your class?
Are all the thumbnails being stored in objThumb...or are you creating many instances of your class and storing them somewhere?

Idle_Mind
0
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

 

Author Comment

by:billin
ID: 12028679
Hi Idle_Mind,

I am storing the images as properties of type IPictureDisp in my thumbnail class, and I am creating many instances of my thumbnail class - one thumbnail per page - and storing all the thumbnails in a collection, which is returned by said function. I had thought at one point that I needed to explicitly clear out the thumbnail collection before allocating a new one, but that was debunked when I was able to crash the program on the first time through the function. That is, there was no thumbnail collection to clear out on the first run, so it couldn't be that.

So the loop in the function goes something like this (I'm just writing this on the fly, so please excuse any mistakes):

Dim objThumb As Thumbnail
Dim objCollection As Collection

For i = 0 To iNumPages
   objThumb = New Thumbnail

   ' Load the relevant graphic page # i here, alter it so that it's thumbnail size, and save it to the
   '    file strThumbnailBMP

   Set picTempPicture = LoadPicture()
   Set picTempPicture = LoadPicture(strThumbnailBMP)
   objThumb.ThumbnailImage = picTempPicture

   objCollection.Add( objThumb )
Next


Since it's always crashing on LoadPicture, there's obviously some crapola going on with LoadPicture that's hogging memory. But if it's really a problem with LoadPicture, which is a commonly used function, I don't know why no one else has seen this before.

Any thoughts?

Regards,
William W. Lin
wlin@cobius.com
0
 

Author Comment

by:billin
ID: 12028954
More info -

In an attempt to narrow down the cause further, I:
1) commented out the call to objCollection.Add( objThumb)
2) Set objThumb = Nothing inbetween loops

It still crashes on a call to LoadPicture as before.

Regards,
William W. Lin
wlin@cobius.com
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 12029504
Sounds like you have done a pretty good job narrowing it down, but try loading your thousand images into a collection without using your class.  Something like:

    Dim objCollection As Collection
    Dim i As StdPicture

    Set objCollection = New Collection
    For i = 0 To iNumPages

        ' Load the relevant graphic page # i here, alter it so that it's thumbnail size, and save it to the file strThumbnailBMP

        Set i = LoadPicture(strThumbnailBMP)
        objCollection.Add i
    Next

Just to see if it pukes still.

Idle_Mind
0
 

Author Comment

by:billin
ID: 12031279
Hey Idle_Mind,

That's a great idea - unfortunately, I removed all references to the thumbnail class entirely (as well as leaving out the call to objCollection.Add), and it still spazzes out on the LoadPicture call. The search continues....

Regards,
Bill
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 400 total points
ID: 12031584
billin,

I can't seem to get LoadPicture() to fail on my system.  Below is how I tested.  I know the error is saying it is actually the LoadPicture() line causing the problem...but seeing as no one else has experienced this I think it has got to be something else.  

The references to out of memory errors I can find are usually related to imagelists or arrays of pictureboxes...

Perhaps your multi-page TIFF code is leaking.  Try making one bitmap and store it on the hard drive.  Then try loading it 2000 times with code like below.

Regards,

Idle_Mind

Option Explicit

Private Sub Form_Load()
    Picture1.AutoSize = True
End Sub

Private Sub Command1_Click()
    Dim i As Integer
    Dim fileName As String
   
    ' Running Win XP Pro v5.1 SP2 with 640mb RAM
    ' JPG is 1024x768 pixels @ 72dpi with bit depth of 24
    fileName = "C:\Documents and Settings\Michael\My Documents\My Pictures\dev7_1024.jpg"
    For i = 1 To 2000
        Picture1.Picture = LoadPicture(fileName)
    Next i
    MsgBox "Done"
End Sub
0
 
LVL 32

Assisted Solution

by:Erick37
Erick37 earned 100 total points
ID: 12032171
I did a test as well. Win XPP v5.1 SP2

I loaded very large BMP pictures into a IPictureDisp array using Loadpicture.  On picture 21 I got a system warning:
"Windows - Virtual Memory Minimum Too Low ... Windows is increasing the size of your virtual memory paging file. During this process, memory requests for some applications may be denied ..."

Shortly afterward, the VB IDE spit out Error 7 at the LoadPicture line.

My previous test of repeatedly loading the SAME picture object yielded no errors.

Maybe there is something funky about the BMP files which you are loading?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 12032340
The same test using IPictureDisp produced no errors either.

    Dim i As Integer
    Dim fileName As String
    Dim img As IPictureDisp
   
    ' Running Win XP Pro v5.1 SP2 with 640mb RAM
    ' JPG is 1024x768 pixels @ 72dpi with bit depth of 24
    fileName = "C:\Documents and Settings\Michael\My Documents\My Pictures\dev7_1024.jpg"
    For i = 1 To 2000
        Set img = LoadPicture(fileName)
        Picture1.Picture = img
        Set img = LoadPicture()
        Label1.Caption = i
        DoEvents
    Next i
    MsgBox "Done"

Idle_Mind
0
 

Author Comment

by:billin
ID: 12560105
Hi Dan,

None of the comments provided an answer, but various comments were helpful. Can I split the points regardless, without accepting one as an answer?

Regards,
William W. Lin
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
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…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

706 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

15 Experts available now in Live!

Get 1:1 Help Now