Jump to content

Recommended Posts

Posted

I'm running some GDI+ code inside a loop and it seems to be leaking memory.  Am I simply doing something wrong?  Below I've reduced my code to the bare minimum.  If I run the below script it slowly grows in memory consumption until stopped ( witnessed via Task Manager ).  It feels like I'm not disposing something or doing something wrong but I can't seem to figure it out.  Does anyone have any suggestions?

Thanks,
 Kendema

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

$hGUI = GUICreate("Form",300,300)
GUISetState(@SW_SHOW)

TestFont()

Func TestFont()
    _GDIPlus_Startup()
    Local $hGraphic, $hFamily, $hFont, $tLayout, $aInfo, $hFormat
    Local $FontSize = 11
    Local $sString = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"

    Do
        $FontSize = 11
        $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
        $hFamily = _GDIPlus_FontFamilyCreate("Arial")
        $hFormat = _GDIPlus_StringFormatCreate()
        $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
        $tLayout = _GDIPlus_RectFCreate(140, 110, 100, 20)

        Do
            $FontSize = $FontSize +1
            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
            $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
        Until $aInfo[2] = 1

        _GDIPlus_FontDispose($hFont)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_GraphicsDispose($hGraphic)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_Shutdown()
EndFunc

 

Posted

Running your code I don't notice any memory leak: consumption is stable.

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Posted

This is for me. 

image.png.f4ed1a35bb9f45cfe3e9692bf59ad3e3.png

Please notice how my pen Paint is so biutifull. 

My video tutorials : ( In construction )  || My Discord : https://discord.gg/S9AnwHw

How to Ask Help ||  UIAutomation From Junkew || WebDriver From Danp2 || And Water's UDFs in the Quote

Spoiler

 Water's UDFs:
Active Directory (NEW 2018-10-19 - Version 1.4.10.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-10-31 - Version 1.3.4.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
 
Tutorials:

ADO - Wiki

 

Posted

SCiTE is 3.6.0, Autoit is 3.3.14.2.  I am running the 32bit version, so will try under the 64bit version to see if makes a difference.   Below is a screen capture with about 5 minutes difference.memuse.jpg.3ec278744d6c82a8cc85f3bdb346f460.jpg

 

Posted

This was my first idea and I tried this variant before answering but didn't observe any difference, but maybe I didn't wait long enough to notice something.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Posted

Thanks @trancexx, really good insight.  I tired the below and it still seem to be leaking memory.  Were you thinking of needing to dispose this somewhere else, if so can you suggest on what I might be overlooking?    Does anyone know if  you have to dispose of the RectFCreate?  I see no function to dispose of that object but all other 'create' statements have a dispose.

Thanks,
 kendama 

 

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

$hGUI = GUICreate("Form",300,300)
GUISetState(@SW_SHOW)

TestFont()

Func TestFont()
    _GDIPlus_Startup()
    Local $hGraphic, $hFamily, $hFont, $tLayout, $aInfo, $hFormat
    Local $FontSize = 11
    Local $sString = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"

    Do
        $FontSize = 11

        Do
            $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
            $hFamily = _GDIPlus_FontFamilyCreate("Arial")
            $hFormat = _GDIPlus_StringFormatCreate()
            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
            $tLayout = _GDIPlus_RectFCreate(140, 110, 100, 20)
            $FontSize = $FontSize +1
            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
            $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
            _GDIPlus_FontDispose($hFont)
            _GDIPlus_FontFamilyDispose($hFamily)
            _GDIPlus_StringFormatDispose($hFormat)
            _GDIPlus_GraphicsDispose($hGraphic)
        Until $aInfo[2] = 1

        ;_GDIPlus_FontDispose($hFont)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_Shutdown()
EndFunc

 

Posted

Here you still dreate two fonts but dispose of only one.

I believe @trancexx is thinking about this:

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

$hGUI = GUICreate("Form",300,300)
GUISetState(@SW_SHOW)

TestFont()

Func TestFont()
    _GDIPlus_Startup()
    Local $hGraphic, $hFamily, $hFont, $tLayout, $aInfo, $hFormat
    Local $FontSize
    Local $sString = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"

    Do
        $FontSize = 11
        $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
        $hFamily = _GDIPlus_FontFamilyCreate("Arial")
        $hFormat = _GDIPlus_StringFormatCreate()
        $tLayout = _GDIPlus_RectFCreate(140, 110, 100, 20)

        Do
            $FontSize = $FontSize +1
            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
            $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
            _GDIPlus_FontDispose($hFont)
        Until $aInfo[2] = 1

        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_GraphicsDispose($hGraphic)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_Shutdown()
EndFunc

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Posted

HI JCHD. I tried that variant also.  I was convinced that it would solve the problem, it did not.  With my example above your reply I both create and dispose within the tighter Do loop and the script still leaks memory.  Any thoughts on how to dispose the RectFCreate of if that's not necessary?

Thanks,

Posted

In the remarks of DllStructCreate function in AutoIt help file, there is, "To release allocated memory just set the returned variable to 0."
So in _GDIPlus_GraphicsMeasureString and in _GDIPlus_RectFCreate, where the returned variable from DllStructCreate() is set to zero, the memory leaking seems to have stopped.

I hope I'm wrong because there are a few functions in GDIPlus.au3 that don't set the DllStructCreate() returned variable to 0. 
Of course a memory leak becomes more apparent when offending functions are in a loop.

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

$hGUI = GUICreate("Form", 300, 300)
GUISetState(@SW_SHOW)

TestFont()

Func TestFont()
    _GDIPlus_Startup()
    Local $hGraphic, $hFamily, $hFont, $tLayout, $aInfo, $hFormat
    Local $FontSize
    Local $sString = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"

    Do
        $FontSize = 11
        $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
        $hFamily = _GDIPlus_FontFamilyCreate("Arial")
        $hFormat = _GDIPlus_StringFormatCreate()
        $tLayout = _GDIPlus_RectFCreate(140, 110, 100, 20)

        Do
            $FontSize = $FontSize + 1
            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
            $aInfo = _GDIPlus_GraphicsMeasureStringEx($hGraphic, $sString, $hFont, $tLayout, $hFormat)
            _GDIPlus_FontDispose($hFont)
        Until $aInfo[2] = 1

        $tLayout = 0 ; This is the returned variable in the creation of the $tagGDIPRECTF Dll structure. (To release allocated memory just set the returned variable to 0)
        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_GraphicsDispose($hGraphic)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_Shutdown()
EndFunc   ;==>TestFont

; This function is a copied version of _GDIPlus_GraphicsMeasureString from the GDIPlus.au3 include file with "$tRECTF = 0" added.
Func _GDIPlus_GraphicsMeasureStringEx($hGraphics, $sString, $hFont, $tLayout, $hFormat)
    Local $tRECTF = DllStructCreate($tagGDIPRECTF)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipMeasureString", "handle", $hGraphics, "wstr", $sString, "int", -1, "handle", $hFont, _
            "struct*", $tLayout, "handle", $hFormat, "struct*", $tRECTF, "int*", 0, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Local $aInfo[3]
    $aInfo[0] = $tRECTF
    $aInfo[1] = $aResult[8]
    $aInfo[2] = $aResult[9]
    $tRECTF = 0 ; Release the resources used by the structure. See remarks of DllStructCreate function in AutoIt help file.

    Return $aInfo
EndFunc   ;==>_GDIPlus_GraphicsMeasureStringEx

 

Posted

I find that surprising because the reassignment should do the sameand free previous memory. Assigning to 0 or anything else should cause the same behavior, isn't it? Zero is just as effective as any other value assigned.

I tried a simplified script to check that my view is correct. Adapt figures to what your computer can handle and have Process Explorer running in the backgroud to notice any increase in working set:

Local $t = DllStructCreate("double[10000000]")
For $i = 1 To 10000
;~  $t = 0
    $t = DllStructCreate("double[10000000]")
Next

10 million doubles is 80Mb at every allocation, so if there was a mem leak by not reassigning $t to 0 it should be very noticeable.

The line $t = 0 may be commented or not there is no change in memory consumption.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Posted

OK, I figured it out.  This issue was that I declared it first near to top of the script:

    Local $hGraphic, $hFamily, $hFont, $tLayout, $aInfo, $hFormat

than assigned a value in the loop:

            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
even though I disposed of it directly after it was still not disposing of the object or something else.

When I removed the reference at the top of the script to $hFont and declared in the loop as:

            Local $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)

then disposed after use, everything works as expected.

Thanks everyone for the help and pointing me in the right direction.

Best,

kendama.

Posted

This is even more cryptic to me. I'm glad that fixed your issue but I don't get why. Or did you not test the amended versions posted?

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Posted
4 hours ago, jchd said:

This is even more cryptic to me. I'm glad that fixed your issue but I don't get why. Or did you not test the amended versions posted?

Tested with your code x86 and x64.  Both stand a little over 10k of memory without any lost even after 50,000 loops...

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

Opt ("MustDeclareVars", 1)

Global $hGUI = GUICreate("Form",300,300)
Global $idLabel = GUICtrlCreateLabel ("0", 50, 50, 100, 20)
GUISetState(@SW_SHOW)

TestFont()

Func TestFont()
    _GDIPlus_Startup()
    Local $hGraphic, $hFamily, $hFont, $tLayout, $aInfo, $hFormat
    Local $FontSize, $Count = 0
    Local $sString = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"

    Do
        $FontSize = 11
        $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
        $hFamily = _GDIPlus_FontFamilyCreate("Arial")
        $hFormat = _GDIPlus_StringFormatCreate()
        $tLayout = _GDIPlus_RectFCreate(140, 110, 100, 20)

        $Count += 1
        ControlSetText ($hGUI, "", $idLabel, $Count)

        Do
            $FontSize = $FontSize +1
            $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 0)
            $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
            _GDIPlus_FontDispose($hFont)
        Until $aInfo[2] = 1

        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_GraphicsDispose($hGraphic)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_Shutdown()
EndFunc

 

Posted

This explains that.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

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
×
×
  • Create New...