是否有可能钩住被GC收集的对象?
本文关键字:对象 GC 有可能 是否 | 更新日期: 2023-09-27 18:18:51
假设我有目标强引用的WeakReference
。我想知道目标对象本身何时被GC收集。这可能吗?
编辑:此处不允许向终结器/析构函数添加代码。我需要的东西是不依赖于类代码
在。net 4.0和之后使用ConditionalWeakTable<TKey, TValue>
是可能的。感谢这个网站和其他网站。它遵循概念验证代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace Test
{
public static class GCInterceptor
{
private static ConditionalWeakTable<object, CallbackRef> _table;
static GCInterceptor()
{
_table = new ConditionalWeakTable<object, CallbackRef>();
}
public static void RegisterGCEvent(this object obj, Action<int> action)
{
CallbackRef callbackRef;
bool found = _table.TryGetValue(obj, out callbackRef);
if (found)
{
callbackRef.Collected += action;
return;
}
int hashCode = RuntimeHelpers.GetHashCode(obj);
callbackRef = new CallbackRef(hashCode);
callbackRef.Collected += action;
_table.Add(obj, callbackRef);
}
public static void DeregisterGCEvent(this object obj, Action<int> action)
{
CallbackRef callbackRef;
bool found = _table.TryGetValue(obj, out callbackRef);
if (!found)
throw new Exception("No events registered");
callbackRef.Collected -= action;
}
private class CallbackRef
{
private int _hashCode;
public event Action<int> Collected;
public CallbackRef(int hashCode)
{
_hashCode = hashCode;
}
~CallbackRef()
{
Action<int> handle = Collected;
if (handle != null)
handle(_hashCode);
}
}
}
}
用以下代码测试:
public partial class Form1 : Form
{
private object _obj;
public Form1()
{
InitializeComponent();
_obj = new object();
_obj.RegisterGCEvent(delegate(int hashCode)
{
MessageBox.Show("Object with hash code " + hashCode + " recently collected");
});
}
private void button1_Click(object sender, EventArgs e)
{
_obj = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
Object.Finalize()
方法如何?它不会在完成时被调用吗?
您可以使用拦截来捕获从自定义接口/类继承的每个类的Finalize。我想,这就是你想要达到的目标,对吧?你可以使用Unity。以下是一个如何使用Unity进行拦截的简短示例。