我在.Net 4中开发的Windows服务有一个奇怪的问题。运行该服务一小时后,内存使用量为274MB。
我试图通过逐个删除功能来找出泄漏的原因,以找出泄漏的原因,因此,所有服务要做的是每10个运行PowerShell命令Get-WBSummary
秒,然后将输出捕获为字符串。
我正在尝试使用Red Gate .Net Profiler 10跟踪占用所有内存的内容。当我查看一个小时后最大的内存消耗时,唯一伸出的是
Namespace Class name Live size (bytes) Unmanaged size (bytes)
System.Reflection RuntimeAssembly 1,400 1,462,189
那不可能是正确的,因为它达到了1.462189mb。
这是我正在使用的代码,每次服务计时器达到10秒时都会运行(为进行测试,我将其设置为较低的值)
var Config = RunspaceConfiguration.Create();
PSSnapInException Warning;
if (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1)
{
Config.AddPSSnapIn("Windows.ServerBackup", out Warning);
}
using (var Runspace = RunspaceFactory.CreateRunspace(Config))
{
Runspace.Open();
PowerShell Ps;
using (Ps = PowerShell.Create())
{
Ps.Runspace = Runspace;
Ps.AddCommand("Get-WBSummary");
var Output = Ps.Invoke();
var Sb = new StringBuilder();
foreach (var PsObject in Output)
{
foreach (var PsPropertyInfo in PsObject.Properties)
{
Sb.AppendLine(PsPropertyInfo.Name + " " + PsPropertyInfo.Value);
}
}
PowershellOutput = Sb.ToString();
}
Runspace.Close();
Runspace.Dispose();
Ps.Dispose();
Config = null;
PowerShellSession.Stop();
PowerShellSession.Dispose();
GC.Collect();
有人可以建议我做错了什么吗?
修改:
这里的问题与C#代码无关,但与我使用PowerShell的方式无关。解决方案不是使用一个PowerShell运行空间并在其中一次又一次地输入相同的命令(这会导致PowerShell内存增加到无穷大),而是每次都创建一个新的PowerShell进程,然后在完成后将其关闭
using (PowerShellProcessInstance ExternalPowerShellProccess = new PowerShellProcessInstance())
{
ExternalPowerShellProccess.Process.Start();
var Config = RunspaceConfiguration.Create();
if (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1)
{
Config.AddPSSnapIn("Windows.ServerBackup", out PSSnapInException Warning);
}
Runspace Runspace = RunspaceFactory.CreateOutOfProcessRunspace(TypeTable.LoadDefaultTypeFiles(), ExternalPowerShellProccess);
Runspace.Open();
using (PowerShell Ps = PowerShell.Create())
{
Ps.Runspace = Runspace;
Ps.AddCommand("Get-WBSummary");
var Output = Ps.Invoke();
var Sb = new StringBuilder();
foreach (var PsObject in Output)
{
foreach (var PsPropertyInfo in PsObject.Properties)
{
Sb.AppendLine(PsPropertyInfo.Name + " " + PsPropertyInfo.Value);
}
}
PowershellOutput = Sb.ToString();
Ps.Dispose();
Runspace.Close();
Runspace.Dispose();
}