GC启动时是否有可能获得事件?我想为每个GC计时,以便查看服务器中的暂停是由于GC还是其他原因。
GC在运行时暂停所有.NET线程,对吗? (当然,除了它运行的线程)。非托管线程怎么样?
谢谢!
答案 0 :(得分:6)
如果您想要做的就是在GC运行时弄清楚,它不会告诉您何时启动,也不会告诉您何时结束,但是如果您可以看到此方法的输出我将在此处描述当您注意到服务器上的暂停时,您应该能够确定GC是否是您的问题。
基本上,你要做的是创建一个带有终结器的类,构造该类的对象,然后删除引用(即不存储它)。然后该对象将被保留,直到GC命中它,它将在那里完成。
现在的诀窍在于你记录的终结器(以任何你想要的方式使用)终结器已经运行,除非appdomain正在关闭,你只需构造一个新的对象,你迅速放弃它参考,为下一个GC做好准备。
这非常有效,并且您不需要做太多工作。
这是我使用的课程:
namespace PresentationMode
{
/// <summary>
/// This class is used to get a running log of the number of garbage collections that occur,
/// when running with logging.
/// </summary>
public sealed class GCLog
{
#region Construction & Destruction
/// <summary>
/// Releases unmanaged resources and performs other cleanup operations before the
/// <see cref="GCLog"/> is reclaimed by garbage collection.
/// </summary>
~GCLog()
{
SiAuto.Main.LogMessage("GARBAGE COLLECTED");
if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted)
new GCLog();
}
#endregion
#region Public Static Methods
/// <summary>
/// Registers this instance.
/// </summary>
public static void Register()
{
#if DEBUG
if (SiAuto.Si.Enabled)
new GCLog();
#endif
}
#endregion
}
}
您所要做的就是调用.Register()
方法。请注意,我使用SmartInspect作为我的日志记录工具,因此您希望将涉及SiAuto
的调用替换为其他内容。
在另一个项目中,同样使用SmartInspect,它有“手表”的概念,您可以在其中发送数值,并在记录工具中绘制它们,我发送值0,1,然后0快速连续,因为这会给我一个始终保持在0的图形,但是当GC运行时会产生尖锐的峰值。将此与监视CPU使用率和使用内存的后台线程相结合,为我提供了非常好的数据。
答案 1 :(得分:3)
这是Profiling API的用途。请参阅ICorProfilerCallback2::GarbageCollectionStarted和GarbageCollectionFinished。
由于这是一个分析器,它显然不适合在生产系统上常规使用。但听起来你对这个主要感兴趣的是用于诊断目的。所以可能值得检查其中一个商业分析器是否已经提供此功能,或者perfmon计数器是否足够 - 编写自己的分析器可能是一个非常重量级的解决方案!
答案 2 :(得分:1)
GC不会发出任何事件,但您可以使用计时器并致电GC.CollectionCount()
查看集合何时发生。
答案 3 :(得分:1)
.net 4有garbage collection events可能对您有用。
答案 4 :(得分:0)
非托管线程不受GC影响。
您可以在性能监视器中看到GC性能,这是一篇关于如何创建系统监视器的文章。我想你可以以某种方式得到GC的反击。
以下是GC使用的perf计数器的说明
答案 5 :(得分:0)
% Time in GC效果计数器应该为您提供所需的数据。
答案 6 :(得分:0)
您可以使用 CLR Hosting 准确监控和测量GC暂停。您可以在这篇文章中找到一个完全相同的示例:Accurately Measuring GC Suspensions。