ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-08-08 21:03:01  阅读:172  来源: 互联网

标签:obj 示例 System 四大 引用 println null public out


一、强引用

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

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

五、小结:

应付面试尔。

标签:obj,示例,System,四大,引用,println,null,public,out
来源: https://www.cnblogs.com/heliusKing/p/13460249.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有