2015-11-16 2 views
0

Я создал функцию для запуска скрипта «Power Shell script». Я использую скрипт запуска Pipeline и Runspace ro (ex: power-get get-service) и запускает 1.000.000 раз скрипт «get-service» Я вижу: - при запуске 1 скрипта (1 конвейер и 1 пробел), затем бара приложение составляет около 300 МБ, при запуске завершено, баран около 70 МБ - ## Заголовок ## при запуске сценария 2,3,4 (с 2,3,4 конвейера и 2,3, ..), а затем приложение приложения высота, это утечка памяти, баран около 1GB, .. и> 2gb. Я вижу проблему с этой позиции: Когда событие процесса pipelineExecutor_OnDataReady, баран, когда вызов этой функции: ConvertToDataTable()Я создал функцию для запуска скрипта «Power Shell script»

DataTable dtTable 
    private void ConvertToDataTable(PSObject psObject, String host) 
    { 
    DataRow dr = dtTable.Rows.Add(); 
    foreach (PSPropertyInfo item in psObject.Properties) 
    {     
    string strvalue = string.Empty; 
        if (item.TypeNameOfValue != "System.Runtime.InteropServices.SafeHandle") 
        if (item.Value != null) 
        {     
         if (item.Value.GetType().FullName == "System.ServiceProcess.ServiceController[]") 
         { 
          ServiceController[] sController = (ServiceController[])item.Value; 
          foreach (ServiceController sCtrler in sController) 
          { 
           if (sCtrler.MachineName != ".") 
           strvalue += sCtrler.ServiceName + ", "; 
          } 
          if (strvalue.Length > 2) 
          strvalue = strvalue.Remove(strvalue.Length - 2); 
          `enter code here`strvalue = "{ " + strvalue + " }"; 
         } 
         if (item.Value.GetType().BaseType.FullName == "System.Array") 
         { 
          var result = ((System.Collections.IEnumerable)item.Value).ToString(); 
          strvalue = string.Join(", ", result); 
          if (!string.IsNullOrEmpty(strvalue)) 
           strvalue = "{ " + strvalue + " }"; 
         } 
         else 
          strvalue = item.Value.ToString(); 
         if (selectedColsList.Contains(item.Name))      
           dr[item.Name] = strvalue;           
        } 
       }       
      } 
4 pipeline run 4 script with each script will run script 1000.000 times get-service and result of script from psoject will add into table, each table 100.000. I see when access to property of psoject then ram is up, if comment call ConvertToDataTable()function, ram is ok. 
Please help me. 
thanks 
Hoang ([email protected]) 

ответ

0

Один вопрос, который я вижу, это то, как вы создаете список имен служб:

ServiceController[] sController = (ServiceController[])item.Value; 
foreach (ServiceController sCtrler in sController) 
{ 
    if (sCtrler.MachineName != ".") 
     strvalue += sCtrler.ServiceName + ", "; 
} 
if (strvalue.Length > 2) 
    strvalue = strvalue.Remove(strvalue.Length - 2); 
strvalue = "{ " + strvalue + " }"; 

Каждый раз, когда вы связываете имя службы с номером strvalue, вы создаете еще один промежуточный string для сбора мусора, который нужно очистить. Обычно это может не быть большим делом, но поскольку вы используете этот код миллионы раз, что, безусловно, может складываться. Одним из вариантов является использование StringBuilder вместо:

ServiceController[] sController = (ServiceController[])item.Value; 

if (sController.Length < 1) 
    strvalue = string.Empty; 
else 
{ 
    StringBuilder serviceNamesBuilder = new StringBuilder(); 
    ServiceController sCtrler = sController[0]; 

    if (sCtrler.MachineName != ".") 
     serviceNamesBuilder.Append(sCtrler.ServiceName); 
    for (int i = 1; i < sController.Length; i++) 
    { 
     sCtrler = sController[i]; 

     if (sCtrler.MachineName != ".") 
      StringBuilder.Append(", ").Append(sCtrler.ServiceName); 
    } 

    strvalue = serviceNamesBuilder.ToString(); 
} 

Кроме того, я вижу, что большую часть цикла включает в себя строительство значение для strvalue, но в конце концов вы потенциально бросить эту работу далеко. Я бы реструктурировал вашу петлю таким образом, чтобы избежать вычисления значения, которое не используется:

foreach (PSPropertyInfo item in psObject.Properties) 
{ 
    if (item.TypeNameOfValue != "System.Runtime.InteropServices.SafeHandle" 
     && item.Value != null 
     && selectedColsList.Contains(item.Name) 
    ) 
    { 
     string strvalue; 

     // Build value of strvalue... 

     dr[item.Name] = strvalue; 
    } 
}