日期:2014-05-18  浏览次数:21101 次

怎样才能知道一个对象是否已经被GC回收?

怎样才能知道一个对象是否已经被GC回收?

或怎样知道一个对象正在被GC回收?这时能否触发一个事件

------解决方案--------------------
楼主给的分真多啊,口水ing!
给你个示例,你就后悔了:我怎么给这么多分啊???
C# code

using System;
using System.Windows.Forms;
namespace GCTest
{
    class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
        }
    }
    public class B
    {
        ~B()//析构函数,垃圾回收时调用,这意味着对继承链中的所有实例递归地调用 Finalize 方法
        {
            MessageBox.Show("我销毁了啊,你别拦住我");
        }
    }
}

------解决方案--------------------
给回收添加通知:
C# code

using System;
using System.Windows.Forms;
namespace GCTest
{
    public delegate void GCEventHandler();
    class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.disposeHandler += new GCEventHandler(b_disposeHandler);
        }

        static void b_disposeHandler()
        {
            MessageBox.Show("正在回收B");
        }
    }
    public class B
    {
        public event GCEventHandler disposeHandler;
        public B()
        {
            disposeHandler += new GCEventHandler(OnGC);
        }
        ~B()//析构函数,垃圾回收时调用
        {
            disposeHandler();
        }
        void OnGC()
        {
            Console.WriteLine("GCEventHandler was called");
        }
    }

------解决方案--------------------
自己写一个吧。
楼主我就缺分,能碰见你太好了,感觉找到党了!
C# code
using System;

namespace GC_Event
{
    // 定义事件委托
    public delegate void ActionEventHandler(object sender, MyEventArgs e);

    // 定义事件参数
    public class MyEventArgs : EventArgs
    {
        // 根据你的实际需要添加变量
        public int Count = 0;

        // 这个一定要保留,它是开关,控制 GC 是否引发用户事件
        public bool Stop = true;
    }

    // 给类起名叫"烈士",我真是太有才了!
    public class Martyr
    {
        // 静态事件参数变量,通过它存储你要传达给事件的信息
        public static MyEventArgs e = new MyEventArgs();

        // 生成事件变量,也是静态的,存储你让事件引发的方法集合
        public static event ActionEventHandler Action = null;

        // 启动对 GC 的跟踪
        public static void Start()
        {
            // 有 e 被用户定义为 null 的可能性,代码写强壮点吧
            if (Martyr.e != null && Martyr.e.Stop == true)
            {
                // 把控制无限循环开关打开,不间断的跟踪 GC
                Martyr.e.Stop = false;
                // 生成一个动态对象,然后直接抛弃,等着GC来回收
                // 从这点上来说,这个动态对象绝对是烈士
                new Martyr();
            }
        }

        // 停止对 GC 的跟踪
        public static void Stop()
        {
            // 把开关关闭,下次垃圾回收就不会触发事件,并停止循环,这个烈士真正的安息了
            if (Martyr.e != null)
                Martyr.e.Stop = true;
        }

        // 析构器,本方法的核心
        // GC只要一工作,就一定会来执行不存在引用的对象的析构器,算是遗体告别仪式吧
        // 我不是不尊敬烈士昂,只不过这个词比较容易让人理解
        ~Martyr()
        {
            // 如果开关不存在了,或者开关关闭,就老老实实地回收,结束
            if (Martyr.e != null)
                if (!Martyr.e.Stop)
                {
                    // 如果开关开着,就触发事件,同样代码写强壮一点,不执行空事件
                    if (Martyr.Action != null)
                        OnAction();
                    // 革命尚未成功,同志仍须努力
                    // 倒下我一个,还有后来人
                    // 再制造个烈士躺那,跟踪下一次 GC 的动作
                    new Martyr();
                }
        }

        // 触发事件
        private void OnAction()
        {
            // 告诉方法是烈士在调用它,虽然躺那了,精神还在,this关键字仍然指向本体
            // 参数 e 用那个静态的, e 也算是包罗万象了
            Martyr.Action(this, Martyr.e);
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            // 把自己的方法传给烈士要执行的事件
            Martyr.Action += new ActionEventHandler(Program.Process);

            // 启动对 GC 的跟踪
            Martyr.Start();
            // 人为制造垃圾回收
            for (int i = 0; i < 100; i++)
            {
                Martyr.e.Count++;
                int[] j = new int[1000000];
                GC.Col