Opened 16 years ago
Closed 16 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 Changed 16 years ago by Valik
comment:2 Changed 16 years ago by PsaltyDS
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 Changed 16 years ago by Valik
- Resolution set to No Bug
- Status changed from new to closed
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.
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Got a smaller example? I honestly don't want to hunt for a memory leak in that much code.