LoadImage Bug
Archives Forums/BlitzMax Bug Reports/LoadImage Bug
| ||
The LoadPixmap functions of the TPixMapLoaders have a memory leak. I found this leak yesterday and thought it was something wrong in my program and it took me quite a while to trace it. But, it turns out that every time a TPixMapLoader fails to load an image, a small amount of memory is leaked. The funny thing about this bug is that depending on the order you import the loaders and what kind of image you are loading, you may not see the bug. Basically, when you call LoadImage, BlitzMax attempts to load the image with each type of loader until it succeeds in finding one that worked or goes through them all. So, if you load a png and it is the first loader BlitzMax attempts to use, then you will not see any memory leaked. But, if you load a png and BlitzMax tries the bmp or jpg loaders first, then some memory is leaked. The code follows. Here is what you can do to test it. When you run this code, BlitzMax will try the png loader first, since it was imported last, then it will try the bmp loader, then the jpg loader. If you load a png, then no memory is leaked, if you load a jpg or bmp, then some memory is leaked. If you attempt to load a file that is not an image, then more memory is leaked, because all of the loaders will fail. So, run the code as is, but replace the path to the image with a path to a file on your hard drive. if you load a png, no leak, if you load any other file, memory will be leaked. Press L to load. And watch the memory usage in the task manager. The more you press L, the mor ememory is leaked. but, if the image is a png, no memory will be leaked at all. And each subsequent press of L will not use more memory. |
| ||
I've tested this at length and I'm not 100% convinced. I'm using Blitzmax 1.34. Firstly, I changed the code to the following, just to speed up the process - note the two underlined changes: SuperStrict Framework brl.max2d Import brl.GLMax2D Import brl.jpgloader Import brl.bmploader Import brl.pngloader SetGraphicsDriver GLMax2DDriver() Graphics(800, 600) While Not AppTerminate() Cls If KeyDown(KEY_L) Local img:TImage For Local i:Int = 0 To 100 img = LoadImage("image.jpg") '<-- Put your file path here. Next End If GCCollect() Flip Wend I *do* notice what appears to be a miniscule memory leak if I hold down the L key for several minutes. However, I get exactly the same behaviour even when I load a PNG image. Over a period of minutes the memory usage slowly crept up to just over 20MB. |
| ||
Can confirm the memory leak under Win7 RC1 (64 Bit) with bmx1.34 rc9. Also, I have reported a similiar issue about 3 months ago: http://www.blitzbasic.com/Community/posts.php?topic=85013 Btw: You don't need the KeyDown-command nor the gfx stuff in the example. |
| ||
I am running the latest version of BlitzMax. The only reason I did it with a KeyHit is so you give the GC time to do its work and let the Task Manager settle down. Yes, the leak is not that large, but it is a leak none the less. What proves it is that the memory usage does not climb if you load an image of the type that is the first PixMap loader, which in the case of this example is a png. If you load a bmp or non image file, it does leak memory. if you really want to see it exacerbated, load a text file or something, not an image file. Then all of the loaders fail and the memory leak is larger. |
| ||
If you take out ALL of the framework and imports (so they all get loaded) and try to load a file that is not an image file, then the memory still leaks. The size of the file makes no difference either. The file you try to load MUST exist though. If the file does not exist, then no memory leaks. My guess is that a file handle is being left open?!?! SuperStrict SetGraphicsDriver GLMax2DDriver() Graphics(800, 600) While Not AppTerminate() Cls If KeyDown(KEY_L) Local img:TImage For Local i:Int = 0 To 100 img = LoadImage("textfile.txt") '<-- Put your file path here. Next End If GCCollect() Flip Wend |
| ||
has this been fixed in the past two months? <sorry for the necro post> |
| ||
After much effort, I've tracked the jpgloader leak down, and have worked out a fix for it. It all goes wrong in loadjpg() of loadjpeg.c Some memory is allocated, but under two circumstances, it isn't freed. The following code section is broken : jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo,(FILE*)stream); if( setjmp(jmp_env) ){return -1;} res=jpeg_read_header(&cinfo,TRUE); if (res!=1) return -1; jpeg_start_decompress(&cinfo); and should be replaced with : jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo,(FILE*)stream); if( setjmp(jmp_env) ){ jpeg_destroy_decompress(&cinfo); return -1; } res=jpeg_read_header(&cinfo,TRUE); if (res!=1) { jpeg_destroy_decompress(&cinfo); return -1; } jpeg_start_decompress(&cinfo); This removes the leak for me. Have fun :o) |
| ||
You should work for BRL. Or do you?? Anybody who knows: Can this fix be included in the next update? |
| ||
So the problem was only in the jpg loader?!?! Nice one Brucey, good job. Hopefully this will get added to the official source. |
| ||
So the problem was only in the jpg loader?!?! Yep. I've tested them all individually now (using Framework/Import), and I didn't see anything else (obviously) leaking. |
| ||
Hi, Thanks again Brucey! |
| ||
Thanks Brucey! Hope to see this fix included in the next update :) |
| ||
Could someone please check the PNG Loader as well? I'm getting a leak with this one too... :( |
| ||
Good job, Brucie! :-) Edit: Oops.. it's a bug solved 1 month ago. I drunk too much tonight. :P |