• Java - Object#finalize在JDK9中被标记废弃了!


    Java - Object#finalize在JDK9中被标记废弃了!

    时间:2022年12月6日01:34:10
    目录:
    ① 为什么要废弃?
    ② 废弃后,使用什么方式主动监测对象是否被回收?


    一、为什么要废弃?

    ⚡注意:废弃≠移除

    在这里插入图片描述
    在这里插入图片描述


    二、可以使用什么方法检测对象被回收呢?(使用Cleaner✔️)
    • 可参考源码:DirectByteBuffer⚡⚡⚡
      • import jdk.internal.ref.Cleaner;
      • –add-opens java.base/jdk.internal.ref=ALL-UNNAMED → 请继续阅读【三】,将会使用另一个Cleaner🚀

    Cleaner使用示例:

    import java.util.concurrent.TimeUnit;
    
    public class CleanerTest {
        public static void main(String[] args) {
            User user1 = new User();
            User user2 = new User();
            System.out.println(user1);
            System.out.println(user2);
            System.gc();
            user1 = user2 = null;
            System.gc();
    
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { throw new RuntimeException(e); }
        }
    }
    
    
    或者
    
    
    public class CleanerTest {
        public static void main(String[] args) {
            try (
                    User user1 = new User();
                    User user2 = new User();
            ) {
                System.out.println(user1);
                System.out.println(user2);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    import com.baomidou.mybatisplus.core.toolkit.IdWorker;
    import jdk.internal.ref.Cleaner;
    import lombok.EqualsAndHashCode;
    import lombok.ToString;
    
    import java.io.Closeable;
    
    
    @EqualsAndHashCode
    public class User implements Closeable {
        private final Cleaner cleaner;
        private final _User user;
    
        public User() {
            user = new _User();
            cleaner = Cleaner.create(this, user);
        }
    
        @Override
        public String toString() {
            return user.toString();
        }
    
        @Override
        public void close() {
            cleaner.clean();
        }
    
        @EqualsAndHashCode
        @ToString
        private static class _User implements Runnable {
            private final String id;
    
            public _User() {
                id = IdWorker.get32UUID();
            }
    
            @Override
            public void run() {
                System.out.printf("哦不! 我(%s)要被回收了!%n", id);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    三、两个Cleaner!(推荐使用 java.lang.ref.Cleaner + Closeable)

    在这里插入图片描述
    在这里插入图片描述

    1.使用Cleaner示例(推荐):
    import java.util.concurrent.TimeUnit;
    
    public class CleanerTest {
        public static void main(String[] args) {
            User user1 = new User();
            User user2 = new User();
            System.out.println(user1);
            System.out.println(user2);
            System.gc();
            user1 = user2 = null;
            System.gc();
    
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { throw new RuntimeException(e); }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    import com.baomidou.mybatisplus.core.toolkit.IdWorker;
    import lombok.EqualsAndHashCode;
    import lombok.ToString;
    
    import java.lang.ref.Cleaner;
    
    
    @EqualsAndHashCode
    public class User {
        private final String id;
        private final Cleaner cleaner = Cleaner.create();
        private final Cleaner.Cleanable cleanable;
    
        public User() {
            this.id = IdWorker.get32UUID();
            cleanable = cleaner.register(this, new State());
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id='" + id + '\'' +
                    '}';
        }
    
        @EqualsAndHashCode
        @ToString
        private static class State implements Runnable {
    
            public State() {
                System.out.println("[构造中...]: 这里一般通过参数获取堆外内存地址等信息。");
            }
    
            @Override
            public void run() {
                System.out.println("[回收中...]:这里一般根据堆外内存地址等信息,完成堆外内存释放。");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39


    官方还推荐将要特定被回收的类实现Closeable接口,用于资源自动回收

    import com.baomidou.mybatisplus.core.toolkit.IdWorker;
    import lombok.EqualsAndHashCode;
    import lombok.ToString;
    
    import java.io.Closeable;
    import java.lang.ref.Cleaner;
    
    
    @EqualsAndHashCode
    public class User implements Closeable {
        private final String id;
        private final Cleaner cleaner = Cleaner.create();
        private final Cleaner.Cleanable cleanable;
    
        public User() {
            this.id = IdWorker.get32UUID();
            cleanable = cleaner.register(this, new State());
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id='" + id + '\'' +
                    '}';
        }
    
        @Override
        public void close() {
            // Cleaner.Cleanable
            cleanable.clean();
        }
    
    
        @EqualsAndHashCode
        @ToString
        private static class State implements Runnable {
    
            public State() {
                System.out.println("[构造中...]: 这里一般通过参数获取堆外内存地址等信息。");
            }
    
            @Override
            public void run() {
                System.out.println("[回收中...]:这里一般根据堆外内存地址等信息,完成堆外内存释放。");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    public class CleanerTest {
        public static void main(String[] args) {
            try (
                    User user1 = new User();
                    User user2 = new User();
            ) {
                System.out.println(user1);
                System.out.println(user2);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    2. 结果测试

    在这里插入图片描述

  • 相关阅读:
    【Axure教程】自定义显示隐藏的中继器表格
    软件设计模式详解 UML类图 六大设计原则
    软件测试培训靠谱吗?2个月的软件测试培训班能到底能学到技术么?
    Linux基础知识,这里有很多内容可以看看~
    目的:ubuntu下编译GLFW库
    025-从零搭建微服务-文件服务(一)
    3.5 动态定位shellcode
    VAE(变分自动编码器)
    R语言CalibrationCurves包绘制带可信区间的校准曲线
    【Oracle】基础知识面试题
  • 原文地址:https://blog.csdn.net/qq_42292831/article/details/128196014