是否可以在外部进程上强制GC?我的意思是没有附加到Visual Studio / windbg等。我知道可以用VS立即窗口这样做。
修改 看起来这可以通过PerfView完成,但我可以找到很多信息,好像这是一个完整的GC或什么。有什么想法吗?
答案 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();
}