Flaccid_Jack Posted September 26, 2020 Share Posted September 26, 2020 (edited) When I am releasing resources such as with _GDIPlus_ImageDispose($hBitmap), if I am reusing $hBitmap many times, do i need to imagedispose for each instance? Example: _GDIPlus_Startup() For $i = 0 To 100 Global $hBitmap = _GDIPlus_ImageLoadFromFile($sBitmap) Global $hBitmap_Resized = _GDIPlus_ImageResize($hBitmap, 60, 60) ;resize image _GDIPlus_ImageSaveToFile ($hBitmap_Resized, @ScriptDir & "\MyBitmap.png" ) $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\MyBitmap.png") ;removed content Next _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hBitmap_Resized) _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() Will the above script cause memory leaks? Thanks! Edited September 26, 2020 by Flaccid_Jack Link to comment Share on other sites More sharing options...
zeenmakr Posted September 26, 2020 Share Posted September 26, 2020 51 minutes ago, Flaccid_Jack said: Will the above script cause memory leaks? it looks fine to me, btw why are you resizing the same image 100x (: Link to comment Share on other sites More sharing options...
JockoDundee Posted September 26, 2020 Share Posted September 26, 2020 Yes, I think it will leak, since only the resources pointed to by the last value of $hbitmap will be released. The other 99 will still be out there somewhere, unreferenced. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
zeenmakr Posted September 26, 2020 Share Posted September 26, 2020 (edited) 33 minutes ago, JockoDundee said: Yes, I think it will leak, since only the resources pointed to by the last value of $hbitmap will be released. The other 99 will still be out there somewhere, unreferenced. my thought is it re-uses the $hBitmap and not create a new var each loop. or should Global $hBitmap be assigned before the for loop like so _GDIPlus_Startup() Global $hBitmap Global $hBitmap_Resized Global $hImage For $i = 0 To 100 $hBitmap = _GDIPlus_ImageLoadFromFile($sBitmap) $hBitmap_Resized = _GDIPlus_ImageResize($hBitmap, 60, 60) ;resize image _GDIPlus_ImageSaveToFile ($hBitmap_Resized, @ScriptDir & "\MyBitmap.png" ) $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\MyBitmap.png") ;removed content Next Edited September 26, 2020 by zeenmakr Link to comment Share on other sites More sharing options...
JockoDundee Posted September 26, 2020 Share Posted September 26, 2020 3 hours ago, zeenmakr said: my thought is it re-uses the $hBitmap and not create a new var each loop. The problem is not with $hBitmap per se. $hBitmap is just a handle pointing to the real bitmap created from the file. And you create 100 of these bitmap in your loop, each time you call _GDIPlus_ImageLoadFromFile(). Same the for the other 2 calls that return new bitmaps. In your original script, you only dispose of 3 of 300, in the last script 0 of 300. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
JockoDundee Posted September 26, 2020 Share Posted September 26, 2020 (edited) 5 hours ago, Flaccid_Jack said: Global $hBitmap, $hBitmap_Resized, $hImage _GDIPlus_Startup() For $i = 0 To 100 $hBitmap = _GDIPlus_ImageLoadFromFile($sBitmap) $hBitmap_Resized = _GDIPlus_ImageResize($hBitmap, 60, 60) ;resize image _GDIPlus_ImageSaveToFile ($hBitmap_Resized, @ScriptDir & "\MyBitmap.png" ) $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\MyBitmap.png") ;removed content _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hBitmap_Resized) _GDIPlus_BitmapDispose($hImage) Next _GDIPlus_Shutdown() do it like that...(Sorry didn’t mean to quote Flaccid_Jack, it’s my reworking Edited September 26, 2020 by JockoDundee Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
zeenmakr Posted September 27, 2020 Share Posted September 27, 2020 5 hours ago, Flaccid_Jack said: Will the above script cause memory leaks? 34 minutes ago, JockoDundee said: The problem is not with $hBitmap per se. $hBitmap is just a handle pointing to the real bitmap created from the file. And you create 100 of these bitmap in your loop, each time you call _GDIPlus_ImageLoadFromFile(). Same the for the other 2 calls that return new bitmaps. mystery solved, each loop creates a new object hence new handle - dispose is must for each cycle. it does not reassign var such as e.g $i += 1 as i was assuming. see screenshot for quick test #include <GDIPlus.au3> Global $sBitmap = @DesktopDir &'\test.png' Global $hBitmap _GDIPlus_Startup() For $i = 1 To 10 $hBitmap = _GDIPlus_ImageLoadFromFile($sBitmap) ConsoleWrite('-->'&@ScriptLineNumber&' | '&$i&': $hBitmap= '&$hBitmap&''&@CRLF) ;Yellow/Orange ;~ _GDIPlus_ImageDispose($hBitmap) Next _GDIPlus_Shutdown() Link to comment Share on other sites More sharing options...
JockoDundee Posted September 27, 2020 Share Posted September 27, 2020 1 hour ago, zeenmakr said: does not reassign var such as e.g $i += 1 as i was assuming but the var $hbitmap does get reassigned, just like $i. its just that $hBitmap is not a bitmap. It’s just a pointer to a bitmap. And the bitmap is where the big memory usage is. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
zeenmakr Posted September 27, 2020 Share Posted September 27, 2020 5 minutes ago, JockoDundee said: but the var $hbitmap does get reassigned, just like $i. its just that $hBitmap is not a bitmap. It’s just a pointer to a bitmap. And the bitmap is where the big memory usage is. i understand, just didn't take the time to explain myself (: Link to comment Share on other sites More sharing options...
JockoDundee Posted September 27, 2020 Share Posted September 27, 2020 (edited) Another question would be, does memory usage increase with each loop iteration? Like in the OP: For $n = 1 To 100 Global $m=$n Next or even For $n = 1 To 100 Local $m=$n Next In autoit at least, I don’t think it does ... Edited September 27, 2020 by JockoDundee Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Flaccid_Jack Posted September 28, 2020 Author Share Posted September 28, 2020 _GDIPlus_Startup() For $i = 0 To 100 Local $sBitmap = $ObjectImage[$i] ;accidently edited this out from first post <----------------------- Global $hBitmap = _GDIPlus_ImageLoadFromFile($sBitmap) Global $hBitmap_Resized = _GDIPlus_ImageResize($hBitmap, 60, 60) ;resize image _GDIPlus_ImageSaveToFile ($hBitmap_Resized, @ScriptDir & "\MyBitmap.png" ) $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\MyBitmap.png") ;removed content Next _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hBitmap_Resized) _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() Sorry, in attempt to cut the fat from my first post for readability, i left out the declaration of $sBitmap. I'm sorry, @JockoDundee and @zeenmakr; but I am not sure what the consensus was. I am currently doing as Jocko had suggested (disposing of resources every loop). I made this post because I want to optimize my script and didn't know if I was wasting processing time by doing so. Link to comment Share on other sites More sharing options...
JockoDundee Posted September 28, 2020 Share Posted September 28, 2020 3 hours ago, Flaccid_Jack said: _GDIPlus_Startup() For $i = 0 To 100 Local $sBitmap = $ObjectImage[$i] ;accidently edited this out from first post <----------------------- Global $hBitmap = _GDIPlus_ImageLoadFromFile($sBitmap) Global $hBitmap_Resized = _GDIPlus_ImageResize($hBitmap, 60, 60) ;resize image _GDIPlus_ImageSaveToFile ($hBitmap_Resized, @ScriptDir & "\MyBitmap.png" ) $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\MyBitmap.png") ;removed content Next _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hBitmap_Resized) _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() Sorry, in attempt to cut the fat from my first post for readability, i left out the declaration of $sBitmap. I'm sorry, @JockoDundee and @zeenmakr; but I am not sure what the consensus was. I am currently doing as Jocko had suggested (disposing of resources every loop). I made this post because I want to optimize my script and didn't know if I was wasting processing time by doing so. Yes, but declaring in the loop doesn’t actually do anything, except save a few characters of source code. On the other hand, I found this UDF that disposes objects for you automatically on the call to GDI Shutdown. Probably doesn’t make much difference in total execution, and you would still temporarily use a lot of memory, but you wouldn’t have to dispose along the way, and the files might appear slightly quicker. Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now