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

     

  • 相关阅读:
    LeetCode 295. Find Median from Data Stream (堆)
    LeetCode 292. Nim Game(博弈论)
    《JavaScript 模式》读书笔记(4)— 函数2
    《JavaScript 模式》读书笔记(4)— 函数1
    《JavaScript 模式》读书笔记(3)— 字面量和构造函数3
    《JavaScript 模式》读书笔记(3)— 字面量和构造函数2
    《JavaScript 模式》读书笔记(3)— 字面量和构造函数1
    《JavaScript 模式》读书笔记(2)— 基本技巧3
    《JavaScript 模式》读书笔记(2)— 基本技巧2
    《JavaScript 模式》读书笔记(2)— 基本技巧1
  • 原文地址:https://www.cnblogs.com/dgwblog/p/11669145.html
Copyright © 2011-2022 走看看