C# System.Management.Automation.Powershell 类在调用 Invoke() 时泄漏内存

标签 c# powershell system.management

我有一个使用 PowerShell 查询系统信息的 C# 测试应用代码,其中有一些简单的函数,如下所示:

public void GetSystemInfo()
{
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddCommand("Get-Disk");      // Get-Disk is an example; this varies
        foreach (PSObject result in ps.Invoke())
        {
            // ...
            // Do work here. Process results, etc...
            // ...
        }
    }
}

这很简单,主要取自 MSDN 示例,如下所示: https://msdn.microsoft.com/en-us/library/dd182449(v=vs.85).aspx

问题是每次调用此函数时,我都可以看到应用程序的内存占用量在增加。占用空间会在调用 ps.Invoke() 时增长,并且永远不会缩小。 我如何处理数据并不重要;我什至可以完全注释掉 foreach 循环的主体,内存永远不会被垃圾回收。

据我所知,通过查看 PowerShell 类 interface ,似乎没有办法强制它自行清理,并且 Dispose() 显然不起作用,因为在 using block 退出后资源仍在内存中泄漏。

这是 C# PowerShell 类实现中的已知错误还是 PowerShell 本身? 是否有人知道解决方案或替代方案(如果可能)?


编辑

我现在也尝试了以下方法,结果相同:

public void GetSystemInfo()
{
    Runspace rs = RunspaceFactory.CreateRunspace();
    rs.Open();

    PowerShell ps = PowerShell.Create();
    ps.Runspace = rs;
    ps.AddCommand("Get-Disk");      // Get-Disk is an example; this varies
    foreach (PSObject result in ps.Invoke())
    {
        // ...
        // Do work here. Process results, etc...
        // ...
    }

    rs.Close();
}

再次强调,非常简单。取自样本here .

我想知道这是否是 Powershell 模块中的已知错误。也许我会开始研究 Powershell 接口(interface)(WMI 等)的替代方案,因为我需要在不确定的长时间内定期调用这些 PS 查询。

最佳答案

C# 库中的 Powershell API 似乎确实存在问题。即使强制进行垃圾收集似乎也无法释放内存。

用 WMI 调用而不是 Powershell 替换所有内容可以消除问题。

关于C# System.Management.Automation.Powershell 类在调用 Invoke() 时泄漏内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35640564/

相关文章:

c# - IDbSet.Add 和 DbEntityEntry.State = EntityState.Added 有什么区别?

powershell - 将 Powershell 开关传递到 Azure 资源管理器模板 (ARM)

powershell - Sort-Object cmdlet 的 -InputObject 参数如何工作?

c# - 如何使用 C# 打印 pdf

C# System.Management 只有 1 个类?

C# COM => 指针 => delphi 接口(interface)

c# - 在 C# 中使用 C++ DLL

c# - Amazon S3 TransferUtility.Upload 在 C# 中挂起

powershell - Powershell意外输出$ _。在字符串中