Java9垃圾回收方法finalize() 原理解析
1:finalize()方法
finallize()方法是Object类的方法,用于在类被GC回收时做一些处理操作,但是JVM并不能保证finalize(0)方法一定被执行,
由于finalize()方法的调用时机具有不确定性,从一个对象变得不可到达开始,到finalize()方法被执行,所花费的时间这段时间是任意长的。我们并不能依赖finalize()方法能及时的回收占用的资源,可能出现的情况是在我们耗尽资源之前,gc却仍未触发,因而通常的做法是提供显示的close()方法供客户端手动调用
所以一般不建议使用finalize方法,JDK9开始已久被废除
总结缺点
1:finalize机制本身就是存在问题的。
2:finalize机制可能会导致性能问题,死锁和线程挂起。
3:finalize中的错误可能导致内存泄漏;如果不在需要时,也没有办法取消垃圾回收;并且没有指定不同执行finalize对象的执行顺序。此外,没有办法保证finlize的执行时间。
遇到这些情况,对象调用finalize方法只有被无限期延后
-观察finalize方法延长类生命周期#
classUser{ publicstaticUseruser=null; @Override protectedvoidfinalize()throwsThrowable{ System.out.println("User-->finalize()"); user=this; } } publicclassFinalizerTest{ publicstaticvoidmain(String[]args)throwsInterruptedException{ Useruser=newUser(); user=null; System.gc(); Thread.sleep(1000); user=User.user; System.out.println(user!=null);//true user=null; System.gc(); Thread.sleep(1000); System.out.println(user!=null);//false } }
-JDk9以前的垃圾回收代码
publicclassFinalizer{ @Override protectedvoidfinalize()throwsThrowable{ System.out.println("Finalizer-->finalize()"); } publicstaticvoidmain(String[]args){ Finalizerf=newFinalizer(); f=null; System.gc();//手动请求gc } } //输出Finalizer-->finalize()
2:Cleaner类的使用
简介:
在Java9以后提供了最终类Clear来代替实现,下面看一下官方例子
packageThread; importjava.lang.ref.Cleaner; publicclassCleaningExampleimplementsAutoCloseable{ privatefinalstaticCleanerCLEANER=Cleaner.create();//创建者模式创建对象 staticclassStateimplementsRunnable{//清理对象下面说 State(){ System.out.println("init"); } @Override publicvoidrun(){ System.out.println("close"); } } privatefinalStatestate; privatefinalCleaner.Cleanablecleanable;//clearner中的接口实现唯一的清理方法 publicCleaningExample(){ super(); this.state=newState(); this.cleanable=CLEANER.register(this,state);//注册清理容器中并且需要清理对象的引用 } @Override publicvoidclose()throwsException{ cleanable.clean();//进行清理操作 } publicstaticvoidmain(String[]args){ while(true){ newCleaningExample(); } } }
上面可以看出:
Cleaner是最终类不能被重写,内部方法基本以静态方法提供掌握例子上面的方法即可
重点指出
staticclassStateimplementsRunnable
- 如果直接在类中直接定义实现,必须提供一个静态内部类(强制),否者不能进行回收原因(:普通内部类局部内部类对于外部类有依赖(引用),无法真正实现内存的释放)
- 可以选择直接定义外部类(较为复杂,需要传递清理引用Cleanable)
什么时候被回收?
*1.注册的Object处于幻象引用状态
*2.显式调用clean方法
实际例子(模版)
publicclassCleaningExampleextendsThreadimplementsAutoCloseable{ privatefinalstaticCleanerCLEANER=Cleaner.create(); privatefinalStatestate; privatefinalCleaner.Cleanablecleanable; publicCleaningExample(){ this.state=newState(); this.cleanable=CLEANER.register(this,state); } @Override publicvoidclose()throwsException{ cleanable.clean(); } @SuppressWarnings("resource") publicstaticvoidmain(String[]args){ while(true){ CleaningExampleexample=newCleaningExample(); } } //模拟业务请求 @Override publicvoidrun(){ System.out.println("数据库海量查询请求................"); } //清理模版 classStateimplementsRunnable{ State(){ System.out.println("<---init--->"); } @Override publicvoidrun(){ System.out.println("<---close--->"); } } }
实现基础
/** *HeadsofaCleanableListforeachreferencetype. */ finalPhantomCleanable>phantomCleanableList; finalWeakCleanable>weakCleanableList; finalSoftCleanable>softCleanableList; //TheReferenceQueueofpendingcleaningactions finalReferenceQueue
在CleanerImpl类进行clearner类的最终实现,看以看到定义的这些个字段,基本上明确了他的基本原理
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。