【问题标题】:I created function to run script of "Power Shell script"我创建了运行“Powershell脚本”脚本的函数
【发布时间】:2015-11-16 04:43:41
【问题描述】:

我创建了运行“Power Shell 脚本”脚本的函数。 我使用 Pipeline 和 Runspace ro 运行脚本(例如:power shell get-service)并运行 1.000.000 次脚本“get-service” 我懂了: - 运行 1 个脚本(1 个管道和 1 个运行空间)时,应用程序的 ram 约为 300MB,运行完成时,ram 约为 70MB - ## Heading ##when run 2,3, 4 script (with 2,3,4 pipeline and 2,3,..) then ram is so hight, it is leaked memory, ram is about 1GB,..和> 2GB。 我从这个位置看到问题:当事件 pipelineExecutor_OnDataReady 进程时,调用此函数时 ram 已启动:ConvertToDataTable()

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 (hoang.cntt@gmail.com)

【问题讨论】:

    标签: pipeline runspace psobject


    【解决方案1】:

    我看到的一个问题是您创建服务名称列表的方式:

    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-26
      • 1970-01-01
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 2018-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      相关资源
      最近更新 更多