Link to home
Start Free TrialLog in
Avatar of billin
billin

asked on

VB6 LoadPicture memory leak?

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
Avatar of AlexFM
AlexFM

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.
Shouldn't the line be:
Set picTempPicture = LoadPicture("") '<< Note the quotes
Avatar of billin

ASKER

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
Avatar of Mike Tomlinson
A long shot:

Try...

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

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
Avatar of billin

ASKER

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?
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
Avatar of billin

ASKER

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
Avatar of billin

ASKER

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
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
Avatar of billin

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Avatar of billin

ASKER

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