zoukankan      html  css  js  c++  java
  • 强、软、弱、虚四大引用示例

    一、强引用

    我们日常使用的都是强引用,如下:

    StringBuffer str = new StringBuffer("Hello World")
    

    强引用的特点:

    • 强引用可以直接访问目标对象
    • 强引用所指向的对象在任何时候都不会被垃圾回收,虚拟机宁愿报OOM,也不会回收强引用所指向的对象
    • 强引用可能会导致内存泄漏

    二、弱引用

    特点:

    • 当堆空间不足时,就会被回收

    使用示例

    /**
     * 虚拟机参数:-Xmx10m
     * 软引用配合引用队列使用,自动入队;也可以不配合引用队列使用
     * @Author Helius
     * @Create 2020-08-08-6:32 下午
     */
    public class SoftRefQ {
        public static class User {
            int id;
            String name;
    
            public User(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            @Override
            public String toString() {
                return "[id = " + id + ", name = " + name + "]";
            }
        }
    
        static ReferenceQueue<User> softQueue = null;
    
        public static class CheckRefQueue extends Thread{
            @Override
            public void run() {
                while (true) {
                    if (softQueue != null) {
                        UserSoftReference obj = null;
                        try {
                            obj =(UserSoftReference) softQueue.remove();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (obj != null) {
                            System.out.println("user id " + obj.uid + " is delete");
                        }
    
                    }
                }
            }
        }
    
        public static class UserSoftReference extends SoftReference<User> {
            int uid;
    
            public UserSoftReference(User referent, ReferenceQueue<? super User> q) {
                super(referent, q);
                this.uid = referent.id;
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread t = new CheckRefQueue();
            t.setDaemon(true);
            t.start();
            User u = new User(1,"mary");
            softQueue = new ReferenceQueue<>();
            UserSoftReference userSoftReference = new UserSoftReference(u, softQueue);
            u = null;
            System.out.println(userSoftReference.get());
            System.gc();
            System.out.println("After GC");
            System.out.println(userSoftReference.get());
    
            System.out.println("try to create byte array and GC");
            byte[] b = new byte[1024 * 925 * 7];
            System.gc();
            System.out.println(userSoftReference.get());
            Thread.sleep(1000);
        }
    
    }
    

    三、弱引用

    特点

    只要有GC就会被回收,一般配合引用队列使用。

    非常使用用来保持可有可无的缓存数据

    使用示例:

    public class WeakRef {
        public static class User {
            int id;
            String name;
    
            public User(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            @Override
            public String toString() {
                return "[id = " + id + ", name = " + name + "]";
            }
        }
    
        public static void main(String[] args) {
            User u = new User(1,"mary");
            WeakReference<User> userWeakRef = new WeakReference<>(u);
            u = null;
            System.out.println(userWeakRef.get());
            System.gc();
            //不管当前内存空间足够与否,都会回收它的内存
            System.out.println("After GC:");
            System.out.println(userWeakRef.get());
    
        }
    }
    

    输出:

    [id = 1, name = mary]
    After GC:
    null
    

    四、虚引用

    一个持有虚引用 的对象,和没有引用几乎是一样的,随时可能被垃圾器回收,当试图通过虚引用get()方法取得强引用时,总是会失败。

    一般和引用队列一起使用,

    使用示例:

    public class TraceCanReliveObj {
        public static TraceCanReliveObj obj;
        static ReferenceQueue<TraceCanReliveObj> phantomQueue = null;
        public static class CheckRefQueue extends Thread {
            @Override
            public void run() {
                while (true) {
                    if (phantomQueue != null) {
                        PhantomReference<TraceCanReliveObj> objt = null;
                        try {
                            objt = (PhantomReference<TraceCanReliveObj>) phantomQueue.remove();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (objt != null) {
                            System.out.println("TraceCanReliveObj is delete");
                        }
                    }
                }
            }
        }
    
        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println("CanReliveObj finalize called");
            obj = this;
        }
    
        @Override
        public String toString() {
            return "I am CanReliveObj";
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread t = new CheckRefQueue();
            t.setDaemon(true);
            t.start();
    
            phantomQueue = new ReferenceQueue<>();
            obj = new TraceCanReliveObj();
            //构造虚引用
            PhantomReference<TraceCanReliveObj> phantomRef = new PhantomReference<>(obj,phantomQueue);
            obj = null;
            System.gc();
            Thread.sleep(1000);
            if (obj == null) {
                System.out.println("obj is null");
            } else {
                System.out.println("obj 可用");
            }
            System.out.println("第2次 GC");
            obj = null;
            System.gc();
            Thread.sleep(1000);
            if (obj == null) {
                System.out.println("obj is null");
            } else {
                System.out.println("obj 可用");
            }
        }
    }
    

    输出:

    CanReliveObj finalize called
    obj 可用
    第2次 GC
    TraceCanReliveObj is delete
    obj is null
    

    五、小结:

    应付面试尔。

  • 相关阅读:
    将vue文件script代码抽取到单独的js文件
    git pull 提示错误:Your local changes to the following files would be overwritten by merge
    vue和uniapp 配置项目基础路径
    XAMPP Access forbidden! Access to the requested directory is only available from the local network.
    postman与newman集成
    postman生成代码段
    Curl命令
    POST方法的Content-type类型
    Selenium Grid 并行的Web测试
    pytorch转ONNX以及TnesorRT的坑
  • 原文地址:https://www.cnblogs.com/heliusKing/p/13460249.html
Copyright © 2011-2022 走看看