C# 是否有任何事件告诉应用程序何时发生垃圾回收?
我正试图找到一种了解垃圾收集的方法。或者,当它已经开始、完成或正在进行时。我真的需要一些与收藏本身相关的活动(我想) 我的问题是我有一个最弱的VentManager(从零开始编写),我有一些清除方法,可以删除和删除不再存在的WeakReference(WeakReferences在字典中)C# 是否有任何事件告诉应用程序何时发生垃圾回收?,c#,events,garbage-collection,C#,Events,Garbage Collection,我正试图找到一种了解垃圾收集的方法。或者,当它已经开始、完成或正在进行时。我真的需要一些与收藏本身相关的活动(我想) 我的问题是我有一个最弱的VentManager(从零开始编写),我有一些清除方法,可以删除和删除不再存在的WeakReference(WeakReferences在字典中) 问题是我必须知道什么时候该“清理”了。当收集器正在做它的事情时,清理会很好。即使是在垃圾收集之后,至少下一次收集会删除这些旧对象 您可以监视.NET内存性能计数器对象。存在第0代、第1代和第2代集合的计数 通
问题是我必须知道什么时候该“清理”了。当收集器正在做它的事情时,清理会很好。即使是在垃圾收集之后,至少下一次收集会删除这些旧对象 您可以监视.NET内存性能计数器对象。存在第0代、第1代和第2代集合的计数
通常在基于GC的系统上,直接引用GC是一种反模式。在尝试使用清除的WeakReference时,您可能会(给出有限的描述)懒散地进行清理更好。System.GC类提供RegisterForFullGCNotification方法,该方法允许在垃圾收集即将完成时以及垃圾收集完成时发出通知 这并不理想,因为使用此方法有一些警告,例如必须禁用并发垃圾收集才能使此方法工作 有关完整信息,请参见以下链接:
如果创建一个废弃对象,该对象具有对对象的传出引用,但没有传入引用,即
new MyGcMonitor(this); // don't store result
如果您确保MyGcMonitor有一个终结器(析构函数),那么在gcfase完成后,将在一个单独的线程上调用该终结器。
终结器可以调用一个方法来告诉您的类终结已经完成
棘手的部分是如果您再次需要它,例如,如果您决定不释放对象。然后,您必须设置一个序列,该序列在运行的GC线程之外创建另一个MyGcMonitor实例。我想您可以使用delegate.invoke,并在该委托中首先调用GC.WaitForPendingFinalizers()
恢复MyGcMonitor也会遇到类似的问题,即稍后删除(静态)引用。以下是我用来记录到SmartInspect的类,说明发生了GC。您应该能够很容易地更改这个类的功能 要启动它,只需调用
GCLog.Register()代码>
#区域文件头
//本文件版权所有©2007 Lasse Vågsæther Karlsen,保留所有权利。
//
//$Id:GCLog.cs1352008-05-2811:28:37Z lassevk$
#端区
#区域使用
使用制度;
使用System.Collections.Generic;
使用系统文本;
使用系统诊断;
使用Gurock.SmartInspect;
#端区
名称空间表示模式
{
///
///此类用于获取发生的垃圾回收次数的运行日志,
///使用日志记录运行时。
///
公共密封类日志
{
#区域建设与破坏
///
///释放非托管资源并在
///通过垃圾收集回收。
///
~GCLog()
{
SiAuto.Main.LogMessage(“垃圾收集”);
如果(!AppDomain.CurrentDomain.IsFinalizingForUnload()&&!Environment.HashutdownStarted)
新GCLog();
}
#端区
#区域公共静态方法
///
///注册此实例。
///
公共静态无效寄存器()
{
#如果调试
如果(SiAuto.Si.已启用)
新GCLog();
#恩迪夫
}
#端区
}
}
在低优先级线程中,您可以使用此简单的静态方法检查应用程序是否需要清理
private static bool NeedsCleaning ()
{
if (DummyRef.IsAlive) {
return false;
}
DummyRef = new WeakReference (new object ());
return true;
}
+1“当您尝试使用清除的WeakReference时,您最好只是懒洋洋地清理。”这是真的,但这可以在另一个线程中完成。正如我所说的,这并不理想,但它确实提供了一种“框架友好”的方式来接收来自垃圾收集器的通知,而无需使用“黑客”代码;通常,当人们谈论GC时,他们对更昂贵的集合感兴趣
private static bool NeedsCleaning ()
{
if (DummyRef.IsAlive) {
return false;
}
DummyRef = new WeakReference (new object ());
return true;
}