关于外部流程的GC

时间:2015-03-03 21:12:28

标签: .net garbage-collection perfview

是否可以在外部进程上强制GC?我的意思是没有附加到Visual Studio / windbg等。我知道可以用VS立即窗口这样做。

修改 enter image description here 看起来这可以通过PerfView完成,但我可以找到很多信息,好像这是一个完整的GC或什么。有什么想法吗?

3 个答案:

答案 0 :(得分:10)

您从外部进程强制GC的选项是

1)附加调试器API并使用该API调用GC.Collect()方法。我最初尝试使用PerfView执行此操作,但如果在本机代码中阻止进程(调试器在再次运行托管代码之前不会附加),则无法执行此操作,这是不可接受的。

2)注入一个分析器(从V4.5开始,你可以使用attach)并在其上调用API来执行GC。这确实有效(假设还没有连接另一个探查器)。这实际上是PerfView的功能。

3)使用Windows事件跟踪(ETW)。从运行时的V4.5开始,有一个名为GCHeapCollect的关键字,如果设置将导致运行时执行完整的GC。您需要成为管理员以启用ETW提供商,因此这仅适用于您控制'进程可以是管理员。如果您希望这样做,请使用TraceEvent Nuget包(请参阅http://blogs.msdn.com/b/vancem/archive/2014/03/15/walk-through-getting-started-with-etw-traceevent-nuget-samples-package.aspx)通常,ETW会向系统上的所有进程发送请求,但您可以使用TraceEventProviderOptions使其处理特定于Win 8或更高版本。

请注意,这些都不适合随意使用。你应该像调试器或分析器那样做这样的事情。在没有他们参与的情况下在其他过程中强制GC通常是邪恶的......

万斯莫里森 .NET Performance Architect。

答案 1 :(得分:2)

不,Windows和.NET都没有公开任何类型的API,您可以使用它来强制外部进程上的GC,而无需在其上附加调试器。

您必须附加调试器并使用该路由强制执行GC。

答案 2 :(得分:1)

如果有人正在寻找通过ETW进行编码的代码(如上述@Vance Morrison所建议),则下面是我使用Microsoft.Diagnostics.Tracing.TraceEvent nuget软件包并修改提供的示例得出的结果。

请注意,可能有更好/更简便的方法来完成此操作,但对于我的用例,它始终如一地工作。

用您的进程ID整数替换<PROCESS_ID>

using (var userSession = new TraceEventSession("TriggerGC"))
{
    userSession.EnableProvider(
        ClrTraceEventParser.ProviderGuid, 
        TraceEventLevel.Verbose, 
        (ulong)(ClrTraceEventParser.Keywords.GCHeapCollect), new TraceEventProviderOptions
        {
            ProcessIDFilter = new List<int>() { <PROCESS_ID> }
        });

    userSession.Source.StopProcessing();    
}