Memory leaks 用于监视系统性能和内存泄漏的VBscript
我有一个简单的脚本,可以在循环中监视Windows XP中进程的不同性能统计信息,直到终止。Memory leaks 用于监视系统性能和内存泄漏的VBscript,memory-leaks,vbscript,Memory Leaks,Vbscript,我有一个简单的脚本,可以在循环中监视Windows XP中进程的不同性能统计信息,直到终止。 尽管我做了很多努力,脚本的内存占用还是会随着时间的推移而增加。 非常感谢您的建议 Set fso = CreateObject("Scripting.FileSystemObject") logFileDirectory = "C:\POSrewrite\data\logs" Dim output Dim filePath filePath = "\SCOPerformance-" &
尽管我做了很多努力,脚本的内存占用还是会随着时间的推移而增加。
非常感谢您的建议
Set fso = CreateObject("Scripting.FileSystemObject")
logFileDirectory = "C:\POSrewrite\data\logs"
Dim output
Dim filePath
filePath = "\SCOPerformance-" & Day(Now()) & Month(Now()) & Year(Now()) & ".log"
IF fso.FolderExists(logFileDirectory) THEN
ELSE
Set objFolder = fso.CreateFolder(logFileDirectory)
END IF
logFilePath = logFileDirectory + filePath + ""
IF (fso.FileExists(logFilePath)) THEN
set logFile = fso.OpenTextFile(logFilePath, 8, True)
output = VBNewLine
output = output & (FormatDateTime(Now()) + " Open log file." & VBNewLine)
ELSE
set logFile = fso.CreateTextFile(logFilePath)
output = output & (FormatDateTime(Now()) + " Create log file." & VBNewLine)
END IF
output = output & (FormatDateTime(Now()) + " Begin Performance Log data." & VBNewLine)
output = output & ( "(Process) (Percent Processor Time) (Working Set(bytes)) (Page Faults Per Second) (PrivateBytes) (PageFileBytes)" & VBNewLine)
WHILE (True)
On Error Resume NEXT
IF Err = 0 THEN
strComputer = "."
Set objRefresher = CreateObject("WbemScripting.SWbemRefresher")
Set objServicesCimv2 = GetObject("winmgmts:\\" _
& strComputer & "\root\cimv2")
Set objRefreshableItem = _
objRefresher.AddEnum(objServicesCimv2 , _
"Win32_PerfFormattedData_PerfProc_Process")
objRefresher.Refresh
' Loop through the processes three times to locate
' and display all the process currently using
' more than 1 % of the process time. Refresh on each pass.
FOR i = 1 TO 3
objRefresher.Refresh
FOR Each Process in objRefreshableItem.ObjectSet
IF Process.PercentProcessorTime > 1 THEN
output = output & (FormatDateTime(Now()) & "," & i ) & _
("," & Process.Name & _
+"," & Process.PercentProcessorTime & "%") & _
("," & Process.WorkingSet) & ("," & Process.PageFaultsPerSec) & _
"," & Process.PrivateBytes & "," & Process.PageFileBytes & VBNewLine
END IF
NEXT
NEXT
ELSE
logFile.WriteLine(FormatDateTime(Now()) + Err.Description)
END IF
logFile.Write(output)
output = Empty
set objRefresher = Nothing
set objServicesCimv2 = Nothing
set objRefreshableItem = Nothing
set objFolder = Nothing
WScript.Sleep(10000)
Wend
我认为脚本的主要问题是在循环中初始化WMI对象,即在循环的每次迭代中,即使这些对象始终相同:
strComputer = "."
Set objRefresher = CreateObject("WbemScripting.SWbemRefresher")
Set objServicesCimv2 = GetObject("winmgmts:\\" _
& strComputer & "\root\cimv2")
Set objRefreshableItem = _
objRefresher.AddEnum(objServicesCimv2 , _
"Win32_PerfFormattedData_PerfProc_Process")
您需要将此代码移出循环,例如,在脚本的开头
其他提示和建议:
- 使用并显式声明脚本中使用的所有变量。声明的变量比未声明的变量稍快
- 用于组合路径的多个部分。这个方法的有用之处在于它为您插入了必要的路径分隔符
logFileDirectory = "C:\POSrewrite\data\logs" filePath = "SCOPerformance-" & Day(Now) & Month(Now) & Year(Now) & ".log" logFilePath = fso.BuildPath(logFileDirectory, filePath)
- 脚本中未使用
变量,因此无需创建它。此外,您还可以按如下方式重写objFolder
检查,使其更具可读性:FolderExists
If Not fso.FolderExists(logFileDirectory) Then fso.CreateFolder logFileDirectory End If
- 将重复代码移动到子程序和函数中,以便于维护:
Function DateTime DateTime = FormatDateTime(Now) End Function ... output = output & DateTime & " Open log file." & vbNewLine
- 连接字符串时通常不需要括号:
output = output & DateTime & "," & i & _ "," & Process.Name & _ "," & Process.PercentProcessorTime & "%" & _ "," & Process.WorkingSet & "," & Process.PageFaultsPerSec & _ "," & Process.PrivateBytes & "," & Process.PageFileBytes & vbNewLine
我遇到了完全相同的问题,将其用于procmon风格的尝试,以捕获似乎正在重生的恶意进程 缩小范围来看,它似乎是对象refresher.Refresh,根本没有办法解决它 为了克服这个问题,我使用了一个for…next来运行它100次,然后立即运行以下命令,这将使脚本重新启动并关闭:
CreateObject("Wscript.Shell").Run """" & WScript.ScriptFullName & """", 0, False
所以我会看着内存从5Mb爬升到40Mb,然后再下降到5Mb谢谢你的及时和详细的回复,Helen。我已尝试将WMI对象移出循环,但我看到的日志输出不一致(缺少进程,for循环中跳过了迭代)。将这些对象移出循环可以显著降低内存泄漏的速度,但它仍然会增长,尽管速度很慢。再次感谢你的帮助。+1这是一个非常详细的答案,值得投票表决。如果可以的话,我已经不止一次地投了赞成票。哇,那真是一篇很棒的文章。我承认从别人糟糕的代码中通过示例学习了VBScript,正如Eric所描述的那样。我总是觉得你必须将变量设置为零(可能)某种COM分配的资源,但很高兴知道事实并非如此,真正的原因是什么。谢谢你!