Jump to content

Can't figure out my memory leak


Recommended Posts

I am created code to monitor a value in an XML file. My code functions, but the memory its using increases without stop. Any ideas on what I am doing wrong?

CODE
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****

#AutoIt3Wrapper_outfile=testXML.exe

#AutoIt3Wrapper_UseUpx=n

#AutoIt3Wrapper_UseAnsi=y

#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GuiConstants.au3>

#Include <_XMLDomWrapper.au3>

#include <Array.au3>

Dim $RetCode, $count, $FileOpen, $RetCode

$Count = 0

While $RetCode = 0

$fileopen = _XMLFileOpen("e:\test.xml")

_WaitForError()

if $RetCode = 2 Then ExitLoop

FileClose($FileOpen)

WEnd

SplashOff()

msgbox(8192,"Failed","ReturnCode=" & $RetCode)

Func _WaitForError();

$RetCode = _GetFirstValue("/Test/RetCode")

EndFunc

Func _GetFirstValue($node)

$ret_val = _XMLGetValue($node)

If IsArray($ret_val) Then

Return ($ret_val[1])

Else

Return SetError(1,3,0)

EndIf

EndFunc

Link to comment
Share on other sites

I thought that FileClose would work since its just closing the handle. I don't want to save the XML or transform the XML. Am I over thinking this?

Why are you using FileClose?! You arent using FileOpen so you should use something like _XMLSaveDoc and/or _XMLTransform.

Hiyoal

Link to comment
Share on other sites

This is a bug of AutoIt with COM - objects. Try to use this _XMLFileOpen:

CODE
;===============================================================================

; Function Name: _XMLFileOpen

; Description: Creates an instance of an XML file.

; Parameter(s): $strXMLFile - the XML file to open

; $strNameSpc - the namespace to specifiy if the file uses one.

; $iVer - specifically try to use the version supplied here.

; $bValOnParse - validate the document as it is being parsed

; Syntax: _XMLFileOpen($strXMLFile, [$strNameSpc], [$iVer], [$bValOnParse] )

; Return Value(s): On Success - 1

; On Failure - -1 and set

; @Error to:

; 0 - No error

; 1 - Parse error, @Extended = MSXML reason

; 2 - No object

; Author(s): Stephen Podhajecki <gehossafats@netmdc.com>

;===============================================================================

Func _XMLFileOpen($strXMLFile, $strNameSpc = "", $iVer = -1, $bValOnParse = True)

If not IsObj($objDoc) then ; only create new DocumentObject, if not exists

;==== pick your poison

If $iVer <> -1 Then

If $iVer > -1 And $iVer < 7 Then

$objDoc = ObjCreate("Msxml2.DOMdocument." & $iVer & ".0")

If IsObj($objDoc) Then

$DOMVERSION = $iVer

EndIf

Else

MsgBox(266288, "Error:", "Failed to create object with MSXML version " & $iVer)

SetError(1)

Return 0

EndIf

Else

For $x = 8 To 0 Step - 1

If FileExists(@SystemDir & "\msxml" & $x & ".dll") Then

$objDoc = ObjCreate("Msxml2.DOMdocument." & $x & ".0")

If IsObj($objDoc) Then

$DOMVERSION = $x

ExitLoop

EndIf

EndIf

Next

EndIf

If Not IsObj($objDoc) Then

_XMLError("Error: MSXML not found. This object is required to use this program.")

SetError(2)

Return -1

EndIf

;Thanks Lukasz Suleja

$oXMLMyError = ObjEvent("AutoIt.Error")

If $oXMLMyError = "" Then

$oXMLMyError = ObjEvent("AutoIt.Error", "_XMLCOMEerr") ; ; Initialize SvenP 's error handler

EndIf

EndIf

$strFile = $strXMLFile

$objDoc.async = False

$objDoc.preserveWhiteSpace = True

$objDoc.validateOnParse = $bValOnParse

if $DOMVERSION > 4 Then $objDoc.setProperty ("ProhibitDTD",false)

$objDoc.Load ($strFile)

$objDoc.setProperty ("SelectionLanguage", "XPath")

$objDoc.setProperty ("SelectionNamespaces", $strNameSpc)

if $objDoc.parseError.errorCode >0 Then consoleWrite($objDoc.parseError.reason&@LF)

If $objDoc.parseError.errorCode <> 0 Then

_XMLError("Error opening specified file: " & $strXMLFile & @CRLF & $objDoc.parseError.reason)

;Tom Hohmann 2008/02/29

SetError(1,$objDoc.parseError.errorCode,-1)

$objDoc = 0

Return -1

EndIf

;Tom Hohmann 2008/02/29

Return 1

EndFunc ;==>_XMLFileOpen

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I still get the same thing with the new function.

This is a bug of AutoIt with COM - objects. Try to use this _XMLFileOpen:

CODE
;===============================================================================

; Function Name: _XMLFileOpen

; Description: Creates an instance of an XML file.

; Parameter(s): $strXMLFile - the XML file to open

; $strNameSpc - the namespace to specifiy if the file uses one.

; $iVer - specifically try to use the version supplied here.

; $bValOnParse - validate the document as it is being parsed

; Syntax: _XMLFileOpen($strXMLFile, [$strNameSpc], [$iVer], [$bValOnParse] )

; Return Value(s): On Success - 1

; On Failure - -1 and set

; @Error to:

; 0 - No error

; 1 - Parse error, @Extended = MSXML reason

; 2 - No object

; Author(s): Stephen Podhajecki <gehossafats@netmdc.com>

;===============================================================================

Func _XMLFileOpen($strXMLFile, $strNameSpc = "", $iVer = -1, $bValOnParse = True)

If not IsObj($objDoc) then ; only create new DocumentObject, if not exists

;==== pick your poison

If $iVer <> -1 Then

If $iVer > -1 And $iVer < 7 Then

$objDoc = ObjCreate("Msxml2.DOMdocument." & $iVer & ".0")

If IsObj($objDoc) Then

$DOMVERSION = $iVer

EndIf

Else

MsgBox(266288, "Error:", "Failed to create object with MSXML version " & $iVer)

SetError(1)

Return 0

EndIf

Else

For $x = 8 To 0 Step - 1

If FileExists(@SystemDir & "\msxml" & $x & ".dll") Then

$objDoc = ObjCreate("Msxml2.DOMdocument." & $x & ".0")

If IsObj($objDoc) Then

$DOMVERSION = $x

ExitLoop

EndIf

EndIf

Next

EndIf

If Not IsObj($objDoc) Then

_XMLError("Error: MSXML not found. This object is required to use this program.")

SetError(2)

Return -1

EndIf

;Thanks Lukasz Suleja

$oXMLMyError = ObjEvent("AutoIt.Error")

If $oXMLMyError = "" Then

$oXMLMyError = ObjEvent("AutoIt.Error", "_XMLCOMEerr") ; ; Initialize SvenP 's error handler

EndIf

EndIf

$strFile = $strXMLFile

$objDoc.async = False

$objDoc.preserveWhiteSpace = True

$objDoc.validateOnParse = $bValOnParse

if $DOMVERSION > 4 Then $objDoc.setProperty ("ProhibitDTD",false)

$objDoc.Load ($strFile)

$objDoc.setProperty ("SelectionLanguage", "XPath")

$objDoc.setProperty ("SelectionNamespaces", $strNameSpc)

if $objDoc.parseError.errorCode >0 Then consoleWrite($objDoc.parseError.reason&@LF)

If $objDoc.parseError.errorCode <> 0 Then

_XMLError("Error opening specified file: " & $strXMLFile & @CRLF & $objDoc.parseError.reason)

;Tom Hohmann 2008/02/29

SetError(1,$objDoc.parseError.errorCode,-1)

$objDoc = 0

Return -1

EndIf

;Tom Hohmann 2008/02/29

Return 1

EndFunc ;==>_XMLFileOpen

Link to comment
Share on other sites

It is working now. The sleep seems to be the answer. I assume that the file was never getting closed before. Here is the code that works. I stripped out the functins that I had as well since they were not really needed.

CODE
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****

#AutoIt3Wrapper_outfile=testXML.exe

#AutoIt3Wrapper_UseUpx=n

#AutoIt3Wrapper_UseAnsi=y

#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GuiConstants.au3>

#Include <_XMLDomWrapper.au3>

#include <Array.au3>

Dim $RetCode, $count, $FileOpen, $RetCode, $node

$Count = 0

;While $RetCode = 0

Do

$fileopen = _XMLFileOpen("test.xml")

$ret_val = _XMLGetValue("/test/RetCode")

$RetCode = $ret_val[1]

if $RetCode = 2 Then ExitLoop

Sleep (500)

FileClose($FileOpen)

Until $RetCode = 2

msgbox(8192,"Failed","ReturnCode=" & $RetCode)

Link to comment
Share on other sites

I assume that the file was never getting closed before.

It isn't getting closed now either, not by FileClose() at least. Your new code probably just leaking at a rate that's harder to notice.

Not sure how you figured that thing about handles, because _XMLFileOpen does not return any handles under any circustances, just -1 on error and 1 on success. There's no file handle to speak of anyway, but COM objects (and new ones are generated for each XMLFileOpen you do, and freeing the memory of old objects does not always work... same leaks can be noticed looping WMI stuff, etc. Maybe not entirely AutoIt's fault).

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

Just checked and you are correct. Still leaking, but not at the pace before. It acts the same with or without the FileClose. Any suggestions?

It isn't getting closed now either, not by FileClose() at least. Your new code probably just leaking at a rate that's harder to notice.

Not sure how you figured that thing about handles, because _XMLFileOpen does not return any handles under any circustances, just -1 on error and 1 on success. There's no file handle to speak of anyway, but COM objects (and new ones are generated for each XMLFileOpen you do, and freeing the memory of old objects does not always work... same leaks can be noticed looping WMI stuff, etc. Maybe not entirely AutoIt's fault).

Link to comment
Share on other sites

It wouldn't break the code, but it would not do what I am trying to accomplish. In the end, this will be running all the time until a different Node = 1. I am trying to update a database with the status of a process I am developing. If I have 100 different scripts running, when each script is finished or fails I will update a database with the current systems status. I could just add the code to all of the different scripts and this would fix the issue. I just don't want to have to rewrite everything unless I absolutely have to.

Would it break the code if you moved the _XMLFileOpen("test.xml") out of the loop?

Link to comment
Share on other sites

In the end, this will be running all the time until a different Node = 1. I am trying to update a database with the status of a process I am developing. If I have 100 different scripts running, when each script is finished or fails I will update a database with the current systems status.

You might want to check the test.xml once, and save the date/time-filestamp somewhere.

Then periodically check the date/time-filestamp of test.xml, if it's the same then you don't have to bother to open and search at all. Only do the complete check if the file has been updated.

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...