C#和Powershell Runspaces造成大量的非托管内存泄漏

时间:2018-06-24 17:45:47

标签: powershell automation

我在.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();
                }

0 个答案:

没有答案