Jump to content

A question from a noob


Recommended Posts

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 by Flaccid_Jack
Link to comment
Share on other sites

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 by zeenmakr
Link to comment
Share on other sites

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

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 by JockoDundee

Code hard, but don’t hard code...

Link to comment
Share on other sites

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()

 

 

_memory_leaks.png

Link to comment
Share on other sites

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

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

_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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...