zoukankan      html  css  js  c++  java
  • Java9以后的垃圾回收

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

     

  • 相关阅读:
    python判断字典中key是否存在
    获取redis中所有的key,清空整个 Redis 服务器的数据
    python redis模块详解
    Windows中redis的下载及安装、设置
    .htaccess
    python介绍
    vi和vim
    其他
    Linux系统相关命令
    Linux用户权限常见命令
  • 原文地址:https://www.cnblogs.com/dgwblog/p/11669145.html
Copyright © 2011-2022 走看看