是否可以在外部进程上强制 GC?我的意思是不附加到 Visual Studio/windbg 等。我知道可以使用 VS 即时窗口之类的东西来做到这一点。
编辑 看起来这可以通过 PerfView 来完成,但我可以找到很多信息,就好像这做了一个完整的 GC 或什么。有任何想法吗?
是否可以在外部进程上强制 GC?我的意思是不附加到 Visual Studio/windbg 等。我知道可以使用 VS 即时窗口之类的东西来做到这一点。
编辑 看起来这可以通过 PerfView 来完成,但我可以找到很多信息,就好像这做了一个完整的 GC 或什么。有任何想法吗?
您从外部进程强制 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 性能架构师。
不,Windows 和 .NET 都没有公开任何类型的 API,您可以在不附加调试器的情况下在外部进程上强制执行 GC。
您必须附加一个调试器并使用该路由来强制进行 GC。
如果有人正在寻找通过 ETW 执行此操作的代码(如上面的@Vance Morrison 所建议),以下是我想出的,使用Microsoft.Diagnostics.Tracing.TraceEvent
nuget 包并调整提供的示例。
注意可能有更好/更简单的方法来做到这一点,但它始终如一地工作,对我的用例没有问题。
替换<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();
}