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方法延长类生命周期
class User{
public static User user = null;
@Override
protected void finalize() throws Throwable {
System.out.println("User-->finalize()");
user = this;
}
}
public class FinalizerTest {
public static void main(String[] args) throws InterruptedException {
User user = new User();
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 以前的垃圾回收代码
public classFinalizer {
@Overrideprotected void finalize() throwsThrowable {
System.out.println("Finalizer-->finalize()");
}public static voidmain(String[] args) {
Finalizer f= newFinalizer();
f= null;
System.gc();//手动请求gc
}
}//输出 Finalizer-->finalize()
2:Cleaner类的使用
简介:
在Java9 以后 提供了最终类Clear来代替实现,下面看一下官方例子
packageThread;importjava.lang.ref.Cleaner;public class CleaningExample implementsAutoCloseable{private final static Cleaner CLEANER=Cleaner.create();// 创建者模式创建对象
staticclass State implementsRunnable{ // 清理对象 下面说
State() {
System.out.println("init");
}
@Overridepublic voidrun() {
System.out.println("close");
}
}private finalState state;private finalCleaner.Cleanable cleanable; // clearner 中的接口 实现唯一的清理方法publicCleaningExample() {super();this.state = newState();this.cleanable=CLEANER.register(this, state); // 注册清理容器中 并且需要清理对象的引用
}
@Overridepublic void close() throwsException {
cleanable.clean(); //进行清理操作
}public static voidmain(String[] args) {while(true) {newCleaningExample();
}
}
}
上面 看出:Cleaner 是最终类 不能被重写, 内部方法基本以静态方法提供 掌握例子上面的方法即可
重点指出
static class State implements Runnable如果直接在类中直接定义实现, 必须提供一个静态内部类 (强制),否者不能进行回收 原因(: 普通内部类 局部内部类 对于外部类有依赖(引用),无法真正实现内存的释放 )
可以选择直接定义外部类 (较为复杂,需要传递清理引用 Cleanable)
什么时候被回收?* 1. 注册的Object处于幻象引用状态
* 2. 显式调用 clean 方法
实际例子(模版)
public class CleaningExample extends Thread implementsAutoCloseable {private final static Cleaner CLEANER =Cleaner.create();private finalState state;private finalCleaner.Cleanable cleanable;publicCleaningExample() {this.state = newState();this.cleanable = CLEANER.register(this, state);
}
@Overridepublic void close() throwsException {
cleanable.clean();
}
@SuppressWarnings("resource")public static voidmain(String[] args) {while (true) {
CleaningExample example= newCleaningExample();
}
}//模拟业务请求
@Overridepublic voidrun() {
System.out.println("数据库 海量 查询请求 ................");
}//清理模版
class State implementsRunnable {
State() {
System.out.println("");
}
@Overridepublic voidrun() {
System.out.println("");
}
}
}
实现基础
/*** Heads of a CleanableList for each reference type.*/
final PhantomCleanable>phantomCleanableList;final WeakCleanable>weakCleanableList;final SoftCleanable>softCleanableList;//The ReferenceQueue of pending cleaning actions
final ReferenceQueue queue;
在CleanerImpl 类进行clearner类的最终实现,看以看到定义的这些个字段,基本上明确了 他的基本原理