java finalizers_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方法延长类生命周期#

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 class Finalizer {

@Override

protected void finalize() throws Throwable {

System.out.println("Finalizer-->finalize()");

}

public static void main(String[] args) {

Finalizer f = new Finalizer();

f = null;

System.gc();//手动请求gc

}

}

//输出 Finalizer-->finalize()

2:Cleaner类的使用

简介:

在Java9 以后 提供了最终类Clear来代替实现,下面看一下官方例子

package Thread;

import java.lang.ref.Cleaner;

public class CleaningExample implements AutoCloseable{

private final static Cleaner CLEANER=Cleaner.create();// 创建者模式创建对象

static class State implements Runnable{ // 清理对象 下面说

State() {

System.out.println("init");

}

@Override

public void run() {

System.out.println("close");

}

}

private final State state;

private final Cleaner.Cleanable cleanable; // clearner 中的接口 实现唯一的清理方法

public CleaningExample() {

super();

this.state = new State();

this.cleanable=CLEANER.register(this, state); // 注册清理容器中 并且需要清理对象的引用

}

@Override

public void close() throws Exception {

cleanable.clean(); //进行清理操作

}

public static void main(String[] args) {

while(true) {

new CleaningExample();

}

}

}

上面可以看出:

Cleaner 是最终类 不能被重写, 内部方法基本以静态方法提供 掌握例子上面的方法即可

重点指出

static class State implements Runnable

如果直接在类中直接定义实现, 必须提供一个静态内部类 (强制),否者不能进行回收 原因(: 普通内部类 局部内部类 对于外部类有依赖(引用),无法真正实现内存的释放 )

可以选择直接定义外部类 (较为复杂,需要传递清理引用 Cleanable)

什么时候被回收?

* 1. 注册的Object处于幻象引用状态

* 2. 显式调用 clean 方法

实际例子(模版)

public class CleaningExample extends Thread implements AutoCloseable {

private final static Cleaner CLEANER = Cleaner.create();

private final State state;

private final Cleaner.Cleanable cleanable;

public CleaningExample() {

this.state = new State();

this.cleanable = CLEANER.register(this, state);

}

@Override

public void close() throws Exception {

cleanable.clean();

}

@SuppressWarnings("resource")

public static void main(String[] args) {

while (true) {

CleaningExample example = new CleaningExample();

}

}

// 模拟业务请求

@Override

public void run() {

System.out.println("数据库 海量 查询请求 ................");

}

// 清理模版

class State implements Runnable {

State() {

System.out.println("");

}

@Override

public void run() {

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类的最终实现,看以看到定义的这些个字段,基本上明确了 他的基本原理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值