外部进程的 GC

GC on external process

是否可以在外部进程上强制执行 GC?我的意思是不附加到 Visual Studio/windbg 等。我知道可以使用 VS Immediate window.

之类的东西来做到这一点

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

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

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

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

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

2) 注入分析器(从 V4.5 开始,您可以使用 attach 执行此操作)并对其调用 API 以执行 GC。这确实有效(假设尚未连接另一个分析器)。这实际上就是 PerfView 所做的。

3) 对 Windows (ETW) 使用事件跟踪。从运行时V4.5开始,有一个关键字叫GCHeapCollect,如果设置它会导致运行时进行一次full GC。您需要成为管理员才能启用 ETW 提供程序,因此这仅在您 'controlling' 进程可以成为管理员时才有效。如果您希望这样做,请使用 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 或更高版本上)。

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

万斯·莫里森 .NET 性能架构师。

如果有人正在寻找通过 ETW 执行此操作的代码(如上面@Vance Morrison 所建议的),下面是我使用 Microsoft.Diagnostics.Tracing.TraceEvent nuget 包并调整示例的结果提供。

注意可能有一种 better/easier 方法可以做到这一点,但它始终如一地工作,对于我的用例来说没有问题。

<PROCESS_ID> 替换为您的进程 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();    
}