楼主给的分真多啊,口水ing! 给你个示例,你就后悔了:我怎么给这么多分啊???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("我销毁了啊,你别拦住我"); } } }对话框会在一段时间后也消失,因为它是B的资源,也被回收了
给回收添加通知: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"); } }
自己写一个吧。 楼主我就缺分,能碰见你太好了,感觉找到党了! 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.Collect(); //Array.Clear(j, 0, 1000000); } Console.WriteLine("第1次试验结束了"); Console.ReadKey(); // 停止对 GC 的跟踪,立杆见影,即使马上 GC 动作,也不会触发事件了 Martyr.Stop(); // 试验一下! for (int i = 100; i < 200; i++) { Martyr.e.Count++; int[] j = new int[1000000]; GC.Collect(); //Array.Clear(j, 0, 1000000); } Console.WriteLine("第2次试验结束了"); Console.ReadKey(); // 再做个试验,自然的执行垃圾回收看看 Martyr.e.Count = 999; Martyr.Start(); // 这个方法不一定会产生 GC 的动作,看内存里垃圾数量怎么样了 GC.Collect(); // 用完别忘了跟烈士告别,否则,嘿嘿,自己试试吧! // 貌似诈尸 Martyr.Stop(); Console.WriteLine("第3次试验结束了"); Console.ReadKey(); } // 用户方法 static void Process(object sender, MyEventArgs e) { // 判断是不是烈士触发的 if (sender is Martyr) Console.WriteLine("循环到第 {0} 次后,垃圾回收器工作,触发事件", e.Count); } } }
一般来说需要知道这个信息的是控件类,而控件类一般都有IsDisposed属性:Control.IsDisposed 属性 例如: if (this.IsDisposed) { //已释放了 }如果没有这样的属性,一般在实现IDisposable 接口的时候会加入这么一个属性来表示对象是否被调用过了Dispose方法而不能再被使用了。
不错 析构听CLR的 12楼的例子很好,构造函数再加上 public Martyr() { Console.WriteLine("我来了!"); } 就更好了!
在你的这个对象里调用一个方法,来判断这个OBJ 是否为空啊?
~Martyr() {
// 如果开关不存在了,或者开关关闭,就老老实实地回收,结束 if (Martyr.e != null) { Console.WriteLine("我可能得走了!"); if (!Martyr.e.Stop) { // 如果开关开着,就触发事件,同样代码写强壮一点,不执行空事件 if (Martyr.Action != null) OnAction(); // 革命尚未成功,同志仍须努力 // 倒下我一个,还有后来人 // 再制造个烈士躺那,跟踪下一次 GC 的动作 new Martyr(); } else { Console.WriteLine("我被踢走了!"); } }
}
怎样才能知道一个对象是否已经被GC回收? ------------ object o = new object(); WeakReference wref = new WeakReference(o); //... if (!wref.IsAlive) Console.WriteLine("已经被GC回收了。"); 如果对象能复活的话,用下面这个: WeakReference wref = new WeakReference(o, true);
Microsoft Content Management Server 2002 .NET Class Reference Resource Members See Also Methods Properties Collapse All Expand All Members Options: Show All Members Options: Filtered Include Inherited Members Include Protected Members .NET Compact Framework Members Only Represents an item, such as an image or other multimedia file, stored in a Microsoft Content Management Server (MCMS) 2002 ResourceGallery.The following tables list the members exposed by the Resource type. Public Properties Name Description CanDelete Gets a value indicating whether the current User has sufficient rights to delete this class instance.(inherited from HierarchyItem) CanSetContent Gets a value indicating whether the current user has sufficient rights to change the content of this Resource using SetContentFromFile. CanSetProperties Gets a value indicating whether the current User has sufficient rights to modify the properties of this class instance.(inherited from HierarchyItem) CanUseForAuthoring Gets a value indicating whether the current user has sufficient rights to use this Resource for authoring a Posting. CreatedBy Gets the User that created this class instance.(inherited from HierarchyItem) CreatedDate Gets the coordinated universal time (UTC) when the HierarchyItem was created.(inherited from HierarchyItem) Description Gets or sets descriptive text for this class instance.(inherited from HierarchyItem) DisplayName Gets or sets the name displayed for a Resource in the MCMS 2002 Web site. DisplayPath Gets the fully-qualified display path of a Resource. FileExtension Gets the extension of the file from which the Resource content was set. Guid Gets a string representation of the globally unique identifier (GUID) for this object.(inherited from HierarchyItem) IsDeleted Gets a value indicating whether this class instance has been deleted, regardless of whether the deletion has been committed. (inherited from HierarchyItem)
详细信息看MSDN:Resource class [MCMS]
但是有个问题: 如果你的对象中的某个字段被其他对象引用,那么垃圾回收器是不会回收这个对象的........... 就像第一个例子中的那个.如果将 B b = new B();这个语句放到一个winform程序里,那么在弹出对话框之后对话框是不会消失的............
给你个示例,你就后悔了:我怎么给这么多分啊???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("我销毁了啊,你别拦住我");
}
}
}对话框会在一段时间后也消失,因为它是B的资源,也被回收了
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");
}
}
http://blog.csdn.net/zjunqiang/archive/2007/10/20/1834129.aspx
楼主我就缺分,能碰见你太好了,感觉找到党了!
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.Collect();
//Array.Clear(j, 0, 1000000);
}
Console.WriteLine("第1次试验结束了");
Console.ReadKey();
// 停止对 GC 的跟踪,立杆见影,即使马上 GC 动作,也不会触发事件了
Martyr.Stop();
// 试验一下!
for (int i = 100; i < 200; i++)
{
Martyr.e.Count++;
int[] j = new int[1000000];
GC.Collect();
//Array.Clear(j, 0, 1000000);
}
Console.WriteLine("第2次试验结束了");
Console.ReadKey();
// 再做个试验,自然的执行垃圾回收看看
Martyr.e.Count = 999;
Martyr.Start();
// 这个方法不一定会产生 GC 的动作,看内存里垃圾数量怎么样了
GC.Collect(); // 用完别忘了跟烈士告别,否则,嘿嘿,自己试试吧!
// 貌似诈尸
Martyr.Stop();
Console.WriteLine("第3次试验结束了");
Console.ReadKey();
} // 用户方法
static void Process(object sender, MyEventArgs e)
{
// 判断是不是烈士触发的
if (sender is Martyr)
Console.WriteLine("循环到第 {0} 次后,垃圾回收器工作,触发事件", e.Count);
}
}
}
例如:
if (this.IsDisposed)
{
//已释放了
}如果没有这样的属性,一般在实现IDisposable 接口的时候会加入这么一个属性来表示对象是否被调用过了Dispose方法而不能再被使用了。
析构听CLR的
12楼的例子很好,构造函数再加上 public Martyr() { Console.WriteLine("我来了!"); }
就更好了!
{
// 如果开关不存在了,或者开关关闭,就老老实实地回收,结束
if (Martyr.e != null)
{
Console.WriteLine("我可能得走了!");
if (!Martyr.e.Stop)
{
// 如果开关开着,就触发事件,同样代码写强壮一点,不执行空事件
if (Martyr.Action != null)
OnAction();
// 革命尚未成功,同志仍须努力
// 倒下我一个,还有后来人
// 再制造个烈士躺那,跟踪下一次 GC 的动作
new Martyr();
}
else { Console.WriteLine("我被踢走了!"); }
}
}
------------
object o = new object();
WeakReference wref = new WeakReference(o);
//...
if (!wref.IsAlive)
Console.WriteLine("已经被GC回收了。");
如果对象能复活的话,用下面这个:
WeakReference wref = new WeakReference(o, true);
Resource Members
See Also Methods Properties
Collapse All Expand All Members Options: Show All Members Options: Filtered
Include Inherited Members
Include Protected Members
.NET Compact Framework Members Only
Represents an item, such as an image or other multimedia file, stored in a Microsoft Content Management Server (MCMS) 2002 ResourceGallery.The following tables list the members exposed by the Resource type. Public Properties
Name Description
CanDelete Gets a value indicating whether the current User has sufficient rights to delete this class instance.(inherited from HierarchyItem)
CanSetContent Gets a value indicating whether the current user has sufficient rights to change the content of this Resource using SetContentFromFile.
CanSetProperties Gets a value indicating whether the current User has sufficient rights to modify the properties of this class instance.(inherited from HierarchyItem)
CanUseForAuthoring Gets a value indicating whether the current user has sufficient rights to use this Resource for authoring a Posting.
CreatedBy Gets the User that created this class instance.(inherited from HierarchyItem)
CreatedDate Gets the coordinated universal time (UTC) when the HierarchyItem was created.(inherited from HierarchyItem)
Description Gets or sets descriptive text for this class instance.(inherited from HierarchyItem)
DisplayName Gets or sets the name displayed for a Resource in the MCMS 2002 Web site.
DisplayPath Gets the fully-qualified display path of a Resource.
FileExtension Gets the extension of the file from which the Resource content was set.
Guid Gets a string representation of the globally unique identifier (GUID) for this object.(inherited from HierarchyItem)
IsDeleted Gets a value indicating whether this class instance has been deleted, regardless of whether the deletion has been committed. (inherited from HierarchyItem)
如果你的对象中的某个字段被其他对象引用,那么垃圾回收器是不会回收这个对象的...........
就像第一个例子中的那个.如果将 B b = new B();这个语句放到一个winform程序里,那么在弹出对话框之后对话框是不会消失的............
{
_gcObj[ID] = 1;//这里可以任意写,但不要写成 _gcObj[ID] = this,否则不能释放
}程序判断:
if (_gcObj[ID] != null)
{
// 对象已回收
}
第二个问题也许能通过获取net框架里面的销毁对象列表可以实现.
你添加个例子:
{System.Threading.Timer t = new System.Threading.Timer(Collect, null, 0, 200);
Console.ReadKey();
t.Dispose();
}
private static void Collect(object o)
{
Console.WriteLine("Timer执行");
GC.Collect();
}
按理说,这里t是不会被回收的,因为后面还有引用。但是执行效果是,gc一直在回收