LoadImage Problem

BlitzMax Forums/BlitzMax Programming/LoadImage Problem

wmaass(Posted 2009) [#1]
I originally posted about this in Brucey's forum thinking it was related to one of his mods but it seems to be related to LoadImage. I did find some other topics on this but they did not have a resolution. Basically, the code below will chew up memory at an alarming rate. Does anybody have any idea on how to fix this or is it a BMax bug?


Import MaxGui.Drivers

Strict




Local w:TGadget = CreateWindow("Mem Test", 10, 10, 1024, 768 )

Local c:TGadget = CreateCanvas(0,0,w.ClientWidth(),w.ClientHeight(),w,0)
c.setlayout 1,1,1,1
CreateTimer( 60 )

While True
        WaitEvent()
        Select EventID()
                Case EVENT_WINDOWCLOSE
                        End
                Case EVENT_TIMERTICK
                        RedrawGadget c
                        
                Case EVENT_GADGETPAINT
                        SetGraphics CanvasGraphics( c )
                               
						Local image:TImage = LoadImage("cats.jpg")
						DrawImage image,0,0
                                
                                Flip
						  image = Null
                                
        EndSelect
Wend




Pete Rigz(Posted 2009) [#2]
The load image should be outside of your main loop. I guess it should be being freed even if it's being loaded every time the gadget is painted, but even so, normally you'd put that outside the loop.

Import MaxGui.Drivers

Strict




Local w:TGadget = CreateWindow("Mem Test", 10, 10, 1024, 768 )

Local c:TGadget = CreateCanvas(0,0,w.ClientWidth(),w.ClientHeight(),w,0)
c.setlayout 1,1,1,1
CreateTimer( 60 )

Local image:TImage = LoadImage("cats.jpg")

While True
        WaitEvent()
        Select EventID()
                Case EVENT_WINDOWCLOSE
                        End
                Case EVENT_TIMERTICK
                        RedrawGadget c
                        
                Case EVENT_GADGETPAINT
                        SetGraphics CanvasGraphics( c )
                               
					
						DrawImage image,0,0
                                
                                Flip
						  image = Null
                                
        EndSelect
Wend



wmaass(Posted 2009) [#3]
The thing is, I need to load it in the main loop - it's dynamic. Ideas?


Brucey(Posted 2009) [#4]
The load image should be outside of your main loop.

Well, insofar as his example shows the loading of a file into the TImage, I would have to agree.
But it's possible one might have a generated TPixmap which needs to be drawn each loop, and it's usually far more efficient to use DrawImage than DrawPixmap.


Pete Rigz(Posted 2009) [#5]
ahh ic, just read the other thread too.

Well, just tried my own test, it certainly does it with loadimage, but not loadanimimage...


wmaass(Posted 2009) [#6]
Sorry for the multiple threads guys.


Pete Rigz(Posted 2009) [#7]
well i say it doesn't do it with loadanimimage, it doesn't if you load an image with more then 1 frame, but if you try with a 1 frame animation it leaks again.


wmaass(Posted 2009) [#8]
Bummer, I was going to try that next.


TaskMaster(Posted 2009) [#9]
I would guess that this is the same bug that I reported a couple months ago. It has to do with the image loaders...

See here:

http://www.blitzmax.com/Community/posts.php?topic=86916#985353


Midimaster(Posted 2009) [#10]
perhaps this helps:

change "Local image:TImage" to "Global image:Timage"

or try to make the local image smaller after drawing it, followed by a garbage collection:

Local image:TImage = LoadImage("cats.jpg")
DrawImage image,0,0
Image=createImage(5,5)
GCCollect() 



wmaass(Posted 2009) [#11]
I think you are right. Unfortunate...I really need this to work - my app is going to be on TV.

I tried some trickery to see if I could fool it into freeing up the resources properly. I created a simple type with a TImage field, then cleared the list right after it was drawn. It seemed to slow down the leak, but did not fix it, no idea why I thought it would.


matibee(Posted 2009) [#12]
I gave it a whirl, and it's not misbehaving for me.

I put a DebugLog GCMemAlloced() right after you null the image handle, which consistantly reports around 40-50k. Watching it with the task manager shows anywhere between 32 to 128k. Neither case is getting out of hand, or leaking. Pretty remarkable really for what you're doing.

Putting a GCCollect() in before the GCMemAlloc(), results in a perfectly stable report of 37k.

Blitzmax V1.33 (where do I find the MaxGUI mod version?)


wmaass(Posted 2009) [#13]
Hmm, I''l try 1.33 or 1.32 next. Maybe it's an issue with 1.35. I've been using task manager to monitor it and the memory gets consumed for sure. I first noticed it when I was stress testing my app and it started to behave badly after 15 minutes or so.


Brucey(Posted 2009) [#14]
On Mac, 1.35, I did some tests and setting it to null before calling collect works as expected.
In fact, it's so efficient that the 20 meg memory allocations (for the image size I was testing) don't even show up on my Leak/memory tool - (That's part of the dev instrument suite that comes with XCode, and is fantastic for finding exactly where every piece of memory in an application has been created, including call stack)

When I dont call collect at that point, it shows many 20 meg allocations, building up for a while, before the GC kicks in and cleans them out.

So yeah, it should work as you would expect.

When you manually call collect, it works using the same parameters as does the "Aggressive" garbage collection mode - I had a rummage around the code to see what's going on.


wmaass(Posted 2009) [#15]
Looks like 1.34 is working for me. The GCCollect after releasing the image is working. Good news!


sebas76(Posted 2010) [#16]
Hi,

I have also a problem with LoadImage in my code :
- I display the same image in 2 different canvas and bmax display only one if I add GCcollect() and random display without.

I use Bmax 1.38/ MaxGui 1.38 on Seven 64 Bits.

No solution found !


sebas76(Posted 2010) [#17]
I found that the bug appear after Bmax 1.30
I have recompiled with Bmax 1.37,1.38,1. 39 a previous version of my software :
Results :
- it works fine with bmax 1.30 + MaxGui 1.30.
- it doesn't work good with all version after ( Image are only display one time then disappears.

So the problem is a bug in Bmax or MaxGui...

It stucks my development, the only way is to go back to Bmax 1.30....


Goober(Posted 2010) [#18]
This function has a known memory leak.

Original topic:
http://www.blitzbasic.com/Community/posts.php?topic=86916#1005040


sebas76(Posted 2010) [#19]
I knew this topic but it doesn't resolve the problem.


SebHoll(Posted 2010) [#20]
- I display the same image in 2 different canvas and bmax display only one if I add GCcollect() and random display without.

Are you definitely calling GLShareContexts() at the start of your code, before you start loading any images?

If that doesn't work, can you tell us which platform you are running on and what graphics driver you are using for Max2D (e.g. DX7/DX9/OpenGL etc.)?


sebas76(Posted 2010) [#21]
Ok I will try GLShareContexts() and see wich driver I use ( I think is OpenGL)


sebas76(Posted 2010) [#22]
It seems to work with GLShareContexts()... I have stucked with that for 2 months...


sebas76(Posted 2011) [#23]
IS there a problem with Loadimage on Intel Chipset G31/33 ?
Because a customer has contacted me for my software that stop when he loads an image ?
Strange because it works on other platform...
Please I need some help.