38

Java9以后的垃圾回收

 4 years ago
source link: https://www.tuicool.com/articles/aMnqEnN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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("<--- init --->");
        }
        @Override
        public void run() {
            System.out.println("<--- close --->");
        }
    }
}

实现基础

    /**
     * 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<Object> queue;

在CleanerImpl 类进行clearner类的最终实现,看以看到定义的这些个字段,基本上明确了 他的基本原理


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK