Modify

Opened 18 years ago

Closed 17 years ago

#520 closed Bug (No Bug)

WMI SwbemRefresher Object used in a loop has memory leak

Reported by: PsaltyDS Owned by:
Milestone: Component: AutoIt
Version: 3.2.12.1 Severity: None
Keywords: WMI SwbemRefresher Cc:

Description

Ref: Example Scripts, _ProcessListProperties() function http://www.autoitscript.com/forum/index.php?showtopic=70538

The _ProcessListProperties() function uses an SwbemRefresher object to get performance data for processes (CPU and MEM usage). If the function is called in a loop, there is a bad memory leak (monitored from Task Manager):

{{{HotKeySet("{ESC}", "_Quit")

; Loop to watch for memory leak
While 1

_ProcessListProperties()
Sleep(500)

WEnd

Func _Quit()

Exit

EndFunc ;==>_Quit
}}}

Moving the creation of the SwbemRefresher outside the function (and loop) so it is only created once, makes the leak go away. (See topic post for code) http://www.autoitscript.com/forum/index.php?s=&showtopic=70538&view=findpost&p=566344

Removing all items and then releasing the object with $oRefresher.DeleteAll and $oRefresher = 0 does not change the memory leak.

Attachments (0)

Change History (3)

comment:1 by Valik, 18 years ago

Got a smaller example? I honestly don't want to hunt for a memory leak in that much code.

comment:2 by PsaltyDS, 18 years ago

Stripped down versions:


This produces the memory leak:

HotKeySet("{ESC}", "_Quit")

Global $oWMI = ObjGet("winmgmts:\\.\root\cimv2")

While 1
	_RunRefresher()
	Sleep(100)
WEnd

Func _Quit()
	Exit
EndFunc   ;==>_Quit

Func _RunRefresher()
	Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
	$colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet
	$oRefresher.Refresh
	Sleep(100)
	$oRefresher.Refresh
	For $oProc In $colProcs
		If $oProc.name = "Explorer" Then ConsoleWrite("Explorer memory use = " & $oProc.WorkingSet & @LF)
	Next
EndFunc   ;==>_RunRefresher

Putting the creation of the refresher outside the loop and only refreshing it inside the loop fixes the memory leak:

HotKeySet("{ESC}", "_Quit")

Global $oWMI = ObjGet("winmgmts:\\.\root\cimv2")
Global $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
$colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet
$oRefresher.Refresh
Sleep(100)

While 1
	_RunRefresher()
	Sleep(200)
WEnd

Func _Quit()
	Exit
EndFunc   ;==>_Quit

Func _RunRefresher()
	$oRefresher.Refresh
	For $oProc In $colProcs
		If $oProc.name = "Explorer" Then ConsoleWrite("Explorer memory use = " & $oProc.WorkingSet & @LF)
	Next
EndFunc   ;==>_RunRefresher

Hope that helps. :-)

comment:3 by Valik, 17 years ago

Resolution: No Bug
Status: newclosed

This is not a leak in AutoIt. I tried calling the Remove() and DeleteAll() methods on the $oRefresher object to get rid of the enumeration but it still leaks. I tested with identical VBS code and it also leaks. Here's the AutoIt code I used:

HotKeySet("{ESC}", "_Quit")

Global $oWMI = ObjGet("winmgmts:\\.\root\cimv2")

While 1
 	Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
	Local $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" )
	Sleep(100)
WEnd

Func _Quit()
	Exit
EndFunc

And the VBS which is identical other than it lacks a hotkey.

Set objServicesCimv2 = GetObject("winmgmts:\\.\root\cimv2")

While True
	Set objRefresher = CreateObject("WbemScripting.SWbemRefresher")
	Set objRefreshableItem = objRefresher.AddEnum(objServicesCimv2 , "Win32_PerfFormattedData_PerfProc_Process")
Wend

Closing as no bug.

Modify Ticket

Action
as closed The ticket will remain with no owner.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.