JVM内存分析系列(五)浅谈finalize()方法
根搜索算法中不可达对象在回收之前,要进行二次标记。
第一次标记时会进行一次筛选:筛选的条件是是否有必要执行finalize()方法。
当对象没有覆盖finalize()方法,或者finalize()被虚拟机调用过,则虚拟机认为没有必要执行finalize()方法。
如果这个对象有必要执行finalize(),则会放在一个队列里,以一个低优先级的线程进行执行finalize()方法进行二次标记,如果在finalize()方法中,对象重新回到引用链上(比如this赋值给其他引用链上的对象),则该对象不被回收,而移出该队列。
注意:finalize()方法只被调用一次,如果这个对象在GC时被调用过一次finalize()方法,则第二次GC的时候,就会被判断为没有必要执行finalize()而被直接回收。
另外finalize()能做的所有工作,都可以通过try-finally更好、更及时的解决。所以请忘掉finalize().
package System.gc; /** * @author piaohailin * @date 2013-12-28 */ public class TestGc { public static TestGc HOOK; @Override protected void finalize() throws Throwable { super.finalize(); TestGc.HOOK = this; System.out.println("finalize"); } /* 输出结果 finalize HOOK is alvie HOOK is dead */ public static void main(String[] args) throws Exception { HOOK = new TestGc(); HOOK = null; System.gc();//第一次GC,符合有必要要执行finalize的条件 Thread.sleep(1000);//Finalizer线程优先级较低,所以要等一会 if (HOOK != null) { System.out.println("HOOK is alvie"); } else { System.out.println("HOOK is dead"); } HOOK = null; System.gc();//第二次GC,因为已经执行过一次finalize,所以没有必要进行二次标记 Thread.sleep(1000);//Finalizer线程优先级较低,所以要等一会 if (HOOK != null) { System.out.println("HOOK is alvie"); } else { System.out.println("HOOK is dead"); } } }
相关推荐
rainchxy 2020-05-14
蚩尤后裔 2019-12-28
sxyyu 2019-11-18
渴望就奋力追寻 2019-11-17
zhll 2019-11-03
Happyunlimited 2019-10-21
爱敲代码的程序员 2015-03-25
zwjweb 2015-01-16
Locksk 2019-06-30
jovisoft 2019-07-01
jovisoft 2019-06-27
huangjing0 2019-06-21
xudongdong 2019-06-20
empireghost 2011-06-09
zhaogezhuoyue 2011-05-10
chenzy的记录 2014-03-14
渴望就奋力追寻 2016-08-18
CodeStore 2010-01-11