简体   繁体   English

C#托管Powershell中的内存泄漏

[英]Memory leaks in C# hosted Powershell

i have a simple app, that's creating a Powershell runspace: 我有一个简单的应用程序,正在创建一个Powershell运行空间:

        var iis = InitialSessionState.CreateDefault();
        iis.ExecutionPolicy = ExecutionPolicy.Unrestricted;
        iis.LanguageMode = PSLanguageMode.FullLanguage;
        iis.ThreadOptions = PSThreadOptions.UseNewThread;
        iis.DisableFormatUpdates = true;

        m_Settings = new PSInvocationSettings
        {
            Host = new PSHostProxy(new PSUIStub()),
        };

        m_RunspacePool = RunspaceFactory.CreateRunspacePool(iis);
        m_RunspacePool.CleanupInterval = new TimeSpan(0, 0, 10);
        m_RunspacePool.SetMaxRunspaces(1);
        m_RunspacePool.SetMinRunspaces(1);
        m_RunspacePool.Open();

And then uses it to execute several PowerShell scripts. 然后使用它执行几个PowerShell脚本。 Each RUN is invoked by external event (runs in another thread) and happens ussualy with 20-50 seconds after the foregoing RUN: 每个RUN由外部事件调用(在另一个线程中运行),并且通常在上述RUN之后的20-50秒内发生:

RUN:
{
  foreach(var scriptName in scripts)
  {
    var ps = PowerShell.Create();
    ps.RunspacePool = m_RunspacePool;
    var input = new PSDataCollection<string>();

    ps.AddCommand(Path.Combine(scriptPath, scriptName));
    ps.AddArgument(args);

    // Call
    ps.Invoke(input, m_Output, m_Settings);
    ...
    m_Output.Clear();
    input.Clear();
    input.Dispose();

    ps.Dispose();
    ps = null;
  }
}

And memory usage of this keeps raising during the run, although the scripts are always the same and even their results are the same. 尽管脚本总是相同的,甚至它们的结果都是相同的,但是在运行期间,这种方法的内存使用量一直在增加。 Each cycle creates a bunch (well like thousands of them, but i suppose the number is given by length of the executed scripts...) of SessionStateCmdLetEntry and those are never disposed and GCed, because of reference by a TimerCallback created by RunspacePoolInternal. 每个周期都会创建一堆SessionStateCmdLetEntry(非常类似于其中的数千个,但是我想数量是由执行脚本的长度给定的...),并且由于由RunspacePoolInternal创建的TimerCallback进行引用,因此永远不会对其进行处置和GC处理。 This can take up to 1GB of memory per day... 每天最多可能需要1GB的内存...

Does anyone have tips, what else should I dispose or clear to avoid stashing the SessionStateCmdLetEntries? 有没有人有提示,为避免隐藏SessionStateCmdLetEntries,我还应该处置或清除其他提示? Or any workarounds for this? 或对此有任何解决方法?

I just need a long running process, that invokes several Powershell scripts and does not eat up memory.. I've also tried not reusing the RunSpacePool and creating a new Runspace for each RUN and even for each script, but it did not help at all... 我只需要一个运行很长时间的过程,该过程将调用多个Powershell脚本并且不会占用内存。所有...

Thanks for any help... 谢谢你的帮助...

It shows out, that the leak is not caused by the C# code, but by a PowerShell script run through this. 它表明泄漏不是由C#代码引起的,而是由运行此脚本的PowerShell脚本引起的。 The script creates its own RunspacePool and PowerShell instance to execute some specific code and this causes the memory leak. 该脚本创建自己的RunspacePool和PowerShell实例以执行一些特定的代码,这会导致内存泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM