C# System.Management.Automation.Powershell class 在调用 Invoke() 时泄漏内存
C# System.Management.Automation.Powershell class leaking memory on Invoke() call
我有一个使用 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 class interface 的了解,似乎没有办法强制它自行清理,而且 Dispose() 显然没有无法正常工作,因为在 using 块退出后资源仍在内存中泄漏。
这是 C# PowerShell class 实现或 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 接口(WMI 等)的替代方案,因为我需要在不确定的长时间内定期调用这些 PS 查询。
C# 库中的 Powershell API 似乎确实存在问题。即使强制进行垃圾收集似乎也无法释放内存。
将所有内容替换为 WMI 调用而不是 Powershell 可以消除问题。
我有一个使用 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 class interface 的了解,似乎没有办法强制它自行清理,而且 Dispose() 显然没有无法正常工作,因为在 using 块退出后资源仍在内存中泄漏。
这是 C# PowerShell class 实现或 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 接口(WMI 等)的替代方案,因为我需要在不确定的长时间内定期调用这些 PS 查询。
C# 库中的 Powershell API 似乎确实存在问题。即使强制进行垃圾收集似乎也无法释放内存。
将所有内容替换为 WMI 调用而不是 Powershell 可以消除问题。