• 强、软、弱、虚四大引用示例


    一、强引用

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

    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项目中svg图标不能正常显示
    Django Rest Framework
    Django contenttype
    Django CKEdirtor配置(图片上传,粘贴,文件上传)
    [SDOI2017] 数字表格
    [SDOI2015] 约数个数和
    [BZOJ4407] 于神之怒加强版
    [SRM625 Div1 Hard] Seatfriends
    [SRM613~] TaroCheckers
    [玲珑杯1138] 震惊,99%的中国人都会算错的问题
  • 原文地址:https://www.cnblogs.com/heliusKing/p/13460249.html
Copyright © 2020-2023  润新知