У меня странная проблема с Windows-сервисом, который я разрабатываю в .Net 4. После часа работы сервиса использование памяти составляет 274 МБ.
Я пытался найти причину утечки, удаляя функции одну за другой, чтобы выяснить, где происходит утечка, и на данный момент из-за этого все, что служба выполняет, - это запускает команду PowerShell Get-WBSummary
каждые 10 секунд и захватить вывод в строку.
Я пытаюсь отследить, что загружает всю память, используя 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();
}