5

是否可以在外部进程上强制 GC?我的意思是不附加到 Visual Studio/windbg 等。我知道可以使用 VS 即时窗口之类的东西来做到这一点。

编辑在此处输入图像描述 看起来这可以通过 PerfView 来完成,但我可以找到很多信息,就好像这做了一个完整的 GC 或什么。有任何想法吗?

4

3 回答 3

14

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

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

2) 注入分析器(从 V4.5 开始,您可以使用附加功能)并在其上调用 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 在其他进程中通常是邪恶的......

Vance Morrison .NET 性能架构师。

于 2015-03-03T23:47:52.060 回答
2

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

您必须附加一个调试器并使用该路由来强制进行 GC。

于 2015-03-03T21:24:48.873 回答
2

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

注意可能有更好/更简单的方法来做到这一点,但它始终如一地工作,对我的用例没有问题。

替换<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();    
}
于 2020-06-11T14:21:53.573 回答