手机网站来几个,建设公司哪家好,博物馆网站微信公众号建设,成都有什么好玩的对象复苏 当一个终止化对象被认为死亡时#xff0c;垃圾收集器可以强制使该对象获得重生#xff08;进入终止化可达队列#xff09;#xff0c;因为这样才能调用对象的Finalize方法。在Finalize方法被调用之后#xff0c;它才算真正的死亡了#xff0c;一个终止化对象会经…对象复苏 当一个终止化对象被认为死亡时垃圾收集器可以强制使该对象获得重生进入终止化可达队列因为这样才能调用对象的Finalize方法。在Finalize方法被调用之后它才算真正的死亡了一个终止化对象会经历死亡重生然后再死亡的过程。该现象被称为复苏resurrection
垃圾收集器将对象的引用放到终止化可达队列对象可达获得了重生调用对象的Finalize方法后再没有任何根指向对象对象真正的死亡。在对象的Finalize方法中将其指针再放入全局静态变量中会怎么样 namespace ResurrectionStudy { class Program { static void Main( string [] args) { SomeType s new SomeType(); } } class SomeType { ~ SomeType() { Console.WriteLine( Finalize ); MyApplication.objHandler this ; } } class MyApplication { public static object objHandler; // 默认为null } } 当执行Finalize时该对象的一个引用将被放入一个根中从而使其可达对象重新复苏后垃圾收集器将不会认为其是可收集的垃圾。但是必须记住该对象已经被执行终止化了使用可能会导致不可预期的结果。如果SomeType还引用了其他对象的字段的话会使被引用的对象都重新复苏但是这些重新复苏的对象中可能一些已经被执行了终止化。 一个不断复苏永不死亡的对象。使用GC的ReRegisterForFinalize方法将指定对象添加到终止化链表的末端会使对象的Finalize方法将再一次被调用。 namespace ResurrectionStudy { class Program { static void Main( string [] args) { SomeType s new SomeType(); } } class SomeType { ~ SomeType() { Console.WriteLine( Finalize ); MyApplication.objHandler this ; GC.ReRegisterForFinalize( this ); } } class MyApplication { public static object objHandler; // 默认为null } } 纯属娱乐如果有需要可以在终止化方法内部根据一定的条件使对象重新复苏。
利用对象复苏设计一个对象池 对象复苏还是很有用的。假设创建一个Expensive对象池。由于对象非常耗费资源创建他需要花费很多的时间出于性能考虑打算在应用程序启动之后就能创建一组Expensive对象然后在应用程序整个生存期中重复地使用。 namespace ResurrectionStudy { class Expensive { static Stack pool new Stack(); // 从对象池中获取对象 public static Expensive GetObjectFromPool() { return (Expensive)pool.Pop(); } // 应用程序关闭时调用该方法销毁对象池 public static void ShutdownThePool() { // 阻止终止化对象被加入对象池 pool null ; } // 创建一个对象并将其添加到对象池中 public Expensive() { pool.Push( this ); } // 当应用程序不再使用对象时Finalize将会被调用 ~ Expensive() { // 如果应用程序没有被关闭将对象重新添加到对象池 if (pool ! null ) { // 调用ReRegisterForFinalize方法使对象以正确的状态加入到对象池 GC.ReRegisterForFinalize( this ); pool.Push( this ); } } } } 当应用程序不再持有Expensive对象的引用如果出现垃圾回收那么Expensive将会被终止化。当Expensive对象的Finalize方法被调用后它会将自己再次加入到对象池中从而使其复苏阻止垃圾收集器回收其内存。 当退出应用程序时将pool字段设为null当应用程序关闭时CLR会为托管堆上的所有对象调用Finalize方法。因为这样子会导致无线循环CLR会在40后强制中断进程。如果pool为null那么Expensive对象将不会再被添加到终止化链表上同时也不会被添加到对象池中Expensive的内存将会被回收。