我正试图找到一种了解垃圾收集的方法。当它已经开始,完成或正在进行时。我真的只需要一些与集合本身相关的事件(我认为)。
我的问题是我有一个WeakEventManager(从头开始编写),我有清除方法,删除和WeakReferences不再存在(WeakReferences在字典中)。
问题是我必须知道何时“清理”。当收集器正在做它的事情时清理它会很好。即使它是在垃圾收集之后,至少下一个集合将删除这些旧对象。
答案 0 :(得分:7)
您可以监视.NET内存性能计数器对象。对于0,1和2集合的数量有计数。
通常在基于GC的系统上,直接引用GC是一种反模式。当您尝试使用已清除的WeakReference时,您可能(给出有限的描述)只是懒得清理。
答案 1 :(得分:7)
System.GC类提供了一个RegisterForFullGCNotification方法,该方法允许在垃圾收集即将完成时以及完成垃圾收集时引发通知。
这并不理想,因为使用此方法有一些注意事项,例如必须禁用并发垃圾收集才能使此方法起作用。
请参阅以下链接以获取完整信息:
答案 2 :(得分:4)
这是我用来登录到GC发生的SmartInspect的类。您应该可以轻松地更改此课程的内容。
要开始使用,只需致电GCLog.Register();
。
#region File Header
// This file Copyright © 2007 Lasse Vågsæther Karlsen, All rights reserved.
//
// $Id: GCLog.cs 135 2008-05-28 11:28:37Z lassevk $
#endregion
#region Using
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Gurock.SmartInspect;
#endregion
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
}
}
答案 3 :(得分:1)
如果您创建一个抛弃对象,该对象具有对象的传出引用但没有传入引用,即
new MyGcMonitor(this); // don't store result
如果确保MyGcMonitor有一个Finalizer(析构函数),那么在GC fase完成之后,将在一个单独的线程上调用该终结器。 终结器可以调用一个方法来告诉你的类完成完成。
棘手的部分是如果你再次需要它,例如你决定不释放你的物体。然后,您必须设置一个序列,该序列在运行的GC线程之外创建另一个MyGcMonitor实例。我想你可以使用delegate.invoke并在该委托中首先调用GC.WaitForPendingFinalizers()。
重新启动MyGcMonitor会有类似的问题,即稍后删除(静态)引用。
答案 4 :(得分:0)
在优先级较低的线程中,您可以使用这种简单的静态方法检查应用程序是否需要清理。
private static bool NeedsCleaning ()
{
if (DummyRef.IsAlive) {
return false;
}
DummyRef = new WeakReference (new object ());
return true;
}