lsakizada Posted April 29, 2008 Share Posted April 29, 2008 I have created a tool to monitor proccesses. The tool is working fine except for one issue. After 3-4 hours the memory of the applicationis growing. I could not find a reason why the memory leak. The memory is leaking only when running the application.can you please help me to fix the problem?The files are locating on this thread: click hereTo see the problem:Compile the MonMon.au3 after1) type a proccess name : lets say svschost.exe for example.Note: You can monitor the monmon.exe 2) Click on Update button.3) Click on the Upper/left button to start monitoring the proccess.keep that tool running couple hour.Notice that the while loop is handling the monitor proccess.Please help... Be Green Now or Never (BGNN)! Link to comment Share on other sites More sharing options...
Zedna Posted April 29, 2008 Share Posted April 29, 2008 I quickly looked at your main script and it looks OK. Try to isolate your problem code. Eliminating method - remove some parts of code and look if it helps solve problem. This way you can find problem part of your code. Then make SIMPLE reproducing script and post your question here again. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
lsakizada Posted April 29, 2008 Author Share Posted April 29, 2008 I quickly looked at your main script and it looks OK.Try to isolate your problem code.Eliminating method - remove some parts of code and look if it helps solve problem. This way you can find problem part of your code.Then make SIMPLE reproducing script and post your question here again.Thanks for the reply.The While loop that handle the monitoring is responsible to the memory leak.I guess the memory leak is an autoit problem. I COULD NOT FIND IT.please look at the loop, it does not do much....thougt. Be Green Now or Never (BGNN)! Link to comment Share on other sites More sharing options...
Siao Posted April 29, 2008 Share Posted April 29, 2008 It's quite easy to deduct that the leak is caused by _ProcessListProperties(), or to be more exact, all that WMI object stuff. "WbemScripting.SWbemRefresher" part leaks more, "winmgmts" less. I don't know much about WMI, maybe there's some proper methods of disconnecting from it or whatever else you are not doing. Assigning 0 to all the object variables after each of the loops doesn't seem to help any. The code overall could be improved in many ways. "be smart, drink your wine" Link to comment Share on other sites More sharing options...
lsakizada Posted April 30, 2008 Author Share Posted April 30, 2008 It's quite easy to deduct that the leak is caused by _ProcessListProperties(), or to be more exact, all that WMI object stuff. "WbemScripting.SWbemRefresher" part leaks more, "winmgmts" less.I don't know much about WMI, maybe there's some proper methods of disconnecting from it or whatever else you are not doing.Assigning 0 to all the object variables after each of the loops doesn't seem to help any.The code overall could be improved in many ways.Hi Sciao, thanks for the reply.I saw that I missed cleeaning the Refresher object.I am adding this code then I will see if it is helps:If IsObj($oRefresher) Then $oRefresher = ""EndIfI agree that the code could be improved in many ways, i created it in few days for my needs only, I will post version 2 with more functionality and better code.I will update regards the memory leak. Be Green Now or Never (BGNN)! Link to comment Share on other sites More sharing options...
lsakizada Posted May 1, 2008 Author Share Posted May 1, 2008 (edited) here is where the memory leak came from: How to fix it please... expandcollapse popup#include <GUIConstants.au3> HotKeySet("{Esc}", "HotKey") While 1 _ProcessListProperties() WEnd Func HotKey() Switch @HotKeyPressed Case "{Esc}" exit EndSwitch EndFunc Func _ProcessListProperties($Process = "", $sComputer = ".") Local $sUserName, $sMsg, $sUserDomain, $avProcs If $Process = "" Then $avProcs = ProcessList() Else $avProcs = ProcessList($Process) EndIf If $avProcs[0][0] = 0 Then Return $avProcs ReDim $avProcs[$avProcs[0][0] + 1][40] $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then $colProcs = $oWMI.ExecQuery("select * from win32_process") If IsObj($colProcs) Then For $oProc In $colProcs For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.ProcessId Then $avProcs[$n][2] = $oProc.ParentProcessId If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName $avProcs[$n][4] = $oProc.Priority $avProcs[$n][5] = $oProc.ExecutablePath $avProcs[$n][8] = $oProc.CommandLine $avProcs[$n][9] = __StringToDate($oProc.CreationDate) $avProcs[$n][10] = $oProc.Description $avProcs[$n][11] = $oProc.ExecutionState $avProcs[$n][12] = $oProc.Handle $avProcs[$n][13] = $oProc.HandleCount $avProcs[$n][14] = $oProc.KernelModeTime $avProcs[$n][15] = $oProc.MaximumWorkingSetSize $avProcs[$n][16] = $oProc.MinimumWorkingSetSize $avProcs[$n][17] = $oProc.OSName $avProcs[$n][18] = $oProc.OSCreationClassName $avProcs[$n][19] = $oProc.OtherOperationCount $avProcs[$n][20] = $oProc.OtherTransferCount $avProcs[$n][21] = $oProc.PageFaults $avProcs[$n][22] = $oProc.PageFileUsage $avProcs[$n][23] = $oProc.PeakPageFileUsage $avProcs[$n][24] = $oProc.PeakVirtualSize $avProcs[$n][25] = $oProc.PrivatePageCount $avProcs[$n][26] = $oProc.QuotaNonPagedPoolUsage $avProcs[$n][27] = $oProc.QuotaPagedPoolUsage $avProcs[$n][28] = $oProc.QuotaPeakNonPagedPoolUsage $avProcs[$n][29] = $oProc.QuotaPeakPagedPoolUsage $avProcs[$n][30] = $oProc.ReadOperationCount $avProcs[$n][31] = $oProc.ReadTransferCount $avProcs[$n][32] = $oProc.SessionId $avProcs[$n][33] = $oProc.Status $avProcs[$n][34] = $oProc.ThreadCount $avProcs[$n][35] = $oProc.UserModeTime $avProcs[$n][36] = $oProc.VirtualSize $avProcs[$n][37] = $oProc.WindowsVersion $avProcs[$n][38] = $oProc.WriteOperationCount $avProcs[$n][39] = $oProc.WriteTransferCount ExitLoop EndIf Next Next Else SetError(2) EndIf Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh Local $iTime = TimerInit() Do Sleep(10) Until TimerDiff($iTime) > 100 $oRefresher.Refresh For $oProc In $colProcs For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then $avProcs[$n][6] = $oProc.PercentProcessorTime $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1) EndIf If IsObj($oWMI) Then $oWMI = "" EndIf If IsObj($oRefresher) Then $oRefresher = "" EndIf Return $avProcs EndFunc;==>_ProcessListProperties Func __StringToDate($dtmDate) Return (StringMid($dtmDate, 5, 2) & "/" & _ StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _ & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate, 13, 2)) EndFunc;==>__StringToDate Edited May 1, 2008 by lsakizada Be Green Now or Never (BGNN)! Link to comment Share on other sites More sharing options...
ChrisL Posted May 1, 2008 Share Posted May 1, 2008 (edited) This isn't really the answer but might help expandcollapse popup#include <GUIConstants.au3> HotKeySet("{Esc}", "HotKey") Global $iTimer = TimerInit() Global $iRestartTimer = 30;seconds While 1 _ProcessListProperties() WEnd Func HotKey() Switch @HotKeyPressed Case "{Esc}" exit EndSwitch EndFunc Func _ProcessListProperties($Process = "", $sComputer = ".") If TimerDiff($iTimer) >= $iRestartTimer * 1000 then ;I don't think killing WMI really helped ;ConsoleWrite("Restart WMI" & @crlf) ;RunWait ("winmgmt /kill","",@SW_Hide) ;RunWait ("Net start winmgmt","",@SW_Hide) ConsoleWrite("Reduce memory" & @crlf) _ReduceMemory(@AutoItPID) $iTimer = TimerInit() EndIf Local $sUserName, $sMsg, $sUserDomain, $avProcs , $oRefresher If $Process = "" Then $avProcs = ProcessList() Else $avProcs = ProcessList($Process) EndIf If $avProcs[0][0] = 0 Then Return $avProcs ReDim $avProcs[$avProcs[0][0] + 1][40] $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then $colProcs = $oWMI.ExecQuery("select * from win32_process") If IsObj($colProcs) Then For $oProc In $colProcs For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.ProcessId Then $avProcs[$n][2] = $oProc.ParentProcessId If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName $avProcs[$n][4] = $oProc.Priority $avProcs[$n][5] = $oProc.ExecutablePath $avProcs[$n][8] = $oProc.CommandLine $avProcs[$n][9] = __StringToDate($oProc.CreationDate) $avProcs[$n][10] = $oProc.Description $avProcs[$n][11] = $oProc.ExecutionState $avProcs[$n][12] = $oProc.Handle $avProcs[$n][13] = $oProc.HandleCount $avProcs[$n][14] = $oProc.KernelModeTime $avProcs[$n][15] = $oProc.MaximumWorkingSetSize $avProcs[$n][16] = $oProc.MinimumWorkingSetSize $avProcs[$n][17] = $oProc.OSName $avProcs[$n][18] = $oProc.OSCreationClassName $avProcs[$n][19] = $oProc.OtherOperationCount $avProcs[$n][20] = $oProc.OtherTransferCount $avProcs[$n][21] = $oProc.PageFaults $avProcs[$n][22] = $oProc.PageFileUsage $avProcs[$n][23] = $oProc.PeakPageFileUsage $avProcs[$n][24] = $oProc.PeakVirtualSize $avProcs[$n][25] = $oProc.PrivatePageCount $avProcs[$n][26] = $oProc.QuotaNonPagedPoolUsage $avProcs[$n][27] = $oProc.QuotaPagedPoolUsage $avProcs[$n][28] = $oProc.QuotaPeakNonPagedPoolUsage $avProcs[$n][29] = $oProc.QuotaPeakPagedPoolUsage $avProcs[$n][30] = $oProc.ReadOperationCount $avProcs[$n][31] = $oProc.ReadTransferCount $avProcs[$n][32] = $oProc.SessionId $avProcs[$n][33] = $oProc.Status $avProcs[$n][34] = $oProc.ThreadCount $avProcs[$n][35] = $oProc.UserModeTime $avProcs[$n][36] = $oProc.VirtualSize $avProcs[$n][37] = $oProc.WindowsVersion $avProcs[$n][38] = $oProc.WriteOperationCount $avProcs[$n][39] = $oProc.WriteTransferCount ExitLoop EndIf Next Next Else SetError(2) EndIf Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh Local $iTime = TimerInit() Do Sleep(10) Until TimerDiff($iTime) > 100 $oRefresher.Refresh For $oProc In $colProcs For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then $avProcs[$n][6] = $oProc.PercentProcessorTime $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1) EndIf If IsObj($oWMI) Then $oWMI = "" EndIf If IsObj($oRefresher) Then $oRefresher = "" EndIf Return $avProcs EndFunc;==>_ProcessListProperties Func __StringToDate($dtmDate) Return (StringMid($dtmDate, 5, 2) & "/" & _ StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _ & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate, 13, 2)) EndFunc;==>__StringToDate Func _ReduceMemory($i_PID = -1) If $i_PID <> -1 Then Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID) Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0]) DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0]) Else Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1) EndIf Return $ai_Return[0] EndFunc I noticed that as soon as you do this $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") the memory shoots up and if you reset the variable$oWMI = 0 and return straight away the memory still keeps climbing So changing the function to this still makes the memory shoot up Func _ProcessListProperties($Process = "", $sComputer = ".") $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2") $oWMI = 0 Return Endfunc This line also makes the memory go up but not come down $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet;this makes the memory increase too Edited May 1, 2008 by ChrisL [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
lsakizada Posted May 1, 2008 Author Share Posted May 1, 2008 This line also makes the memory go up but not come down Yes I just found that Microsoft published that WMI has memory leak when calling it fast enough.. But i could not find fix for it. From Microsofot site: [quote]When you run a program that uses the Windows Management Instrumentation (WMI) service in Microsoft Windows XP, the memory that is used by a remote procedure call (RPC) cache may not be freed, and a memory leak may occur. The RPC cache may grow so large that it causes the program and Windows XP to become unresponsive.[/quote] here is the link to Microsoft site: Be Green Now or Never (BGNN)! Link to comment Share on other sites More sharing options...
ChrisL Posted May 1, 2008 Share Posted May 1, 2008 Yes I found a similar one earlierhttp://support.microsoft.com/default.aspx?...kb;en-us;911262You click the link for the hotfix but you have to request it rather than just download it [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now