千家信息网

java中的引用有哪些

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要讲解了"java中的引用有哪些",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java中的引用有哪些"吧!一、强引用概念:当对象不可达时,即
千家信息网最后更新 2026年11月03日java中的引用有哪些

这篇文章主要讲解了"java中的引用有哪些",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java中的引用有哪些"吧!

一、强引用

概念:当对象不可达时,即可回收。

/** * 强引用。当强引用指针不存在时,对象将被回收 * 也可以理解为 ROOT 引用消失时,对象将被回收 */public class StrongReference {    /**     * jvm在执行gc时 将回调该方法     * @throws Throwable     */    @Override    protected void finalize() throws Throwable {        System.out.println("gc doing now !");    }    public static void main(String[] args) {        StrongReference strongReference = new StrongReference();                // 将引用指针移除        strongReference = null;                // 手动调用gc        System.gc();    }}

二、软引用

概念: 当内存空间不足时,将被回收。

/** * Xmx2oM  设置最大堆内存为20M * 软引用 会在内存空间不够时,进行 gc 操作。 从而 回收 软引用对象 */public class MySoftReference {    public static void main(String[] args) {        SoftReference softReference = new SoftReference(new byte[1024*1024*10]);        System.out.println("第一次gc前 : byte[]:" + softReference.get());        System.gc();        System.out.println("第一次执行gc后 : byte[]:" + softReference.get());        byte[] bytes = new byte[1024*1024*12];        System.out.println("内存不够后 : byte[]:" + softReference.get());    }}

上述代码的补充:源码中,我将虚拟机参数 -Xmx 设置为20M。 我先后 new 出来的 两个byte 数组均超过10M。 目标对象均会存放在老年代中。(按照 新生代 : 老年代 = 1:2.) 大概内存分布为。 老年代 20 * 2/3 约为13.3M。 年轻代 约为 20 * 1/3 约为 6.7M。其中 年轻代 eden:s0:s1 = 8:1:1 故 Eden 约为 5.3 M 。So/S1 约为0.67M。 如下图所示,基本跟计算出来的结果吻合。至于 多出来的部分,个人理解,jvm对计算出的堆大小自我调优勒。

基于对堆内存的分析。可以看出。 第一次 老年代 装入 10 M的 对象。 第二次 想要 装入 12M 对象。肯定装不下。 由于是 软引用。 jvm gc 时会将这部分内容先回收掉。 所以这里没有 出现OOM 的问题。

三、弱引用 (比较重要,面试常考题之一)

备注: ThreadLocal 里使用勒 弱引用。会产生内存泄露的问题。详见 ( https://my.oschina.net/u/4141142/blog/4523523 )

概念:jvm无视该引用。该对象可被弱引用对象获取到对象的实例。 当jvm执行gc时,将直接被回收。(提前条件:没有强引用存在)。

示例一:

/** * 弱引用 虚拟机无视该引用。只要gc 一定会被回收(前提该对象没有被强引用) */public class Test {    public static void main(String[] args) {        Teacher teacher = new Teacher();        WeakReference weakReference = new WeakReference(teacher);        System.out.println(weakReference.get());        // 若不将 teacher 置为null,则还存在一个强引用。不会被gc回收        //teacher = null;        System.gc();        System.out.println(weakReference.get());    }

示例二:

/** * User 对象持有 Teacher 对象的强引用。 * 当teacher 被置为null 时。 teacher 的强应用 随之消失。 * 而 User 对 Teacher 的强引用还在。 故 user.getTeacher() 并不是null * 所以 teacher 并不会被 gc  回收。 * * 当 user 也被置为null时。 user 对 teacher 的强引用也不存在勒。 * 此时 teacher  将会被gc回收 */public class Test1 {public static void main(String[] args) {        User user = new User();        Teacher teacher = new Teacher();        teacher.setName("zs");        user.setTeacher(teacher);        WeakReference weakReference = new WeakReference(teacher);        System.out.println(System.identityHashCode(weakReference.get()));        System.out.println(System.identityHashCode(teacher));        System.out.println(System.identityHashCode(user.getTeacher()));        teacher = null;        System.out.println(user.getTeacher().getName());        // 当user 置为null 时, 对teacher 的强引用消失。 此时 teacher 将会被回收。        user = null;        System.gc();        System.out.println(weakReference.get());    }}

示例三:

public class People extends WeakReference {    public People(Teacher referent) {        super(referent);    }}/** * People 继承自WeakReference  People也是一个虚拟引用对象。 * 所以teacher 被置为null时,强引用指针被清除。 * teacher 就会被gc回收。 */public class Test2 {    public static void main(String[] args) {        Teacher teacher = new Teacher();        People people = new People(teacher);        teacher = null;        System.gc();        System.out.println(people.get());    }}

四、虚引用

概念:该引用很鸡肋。一个对象被虚引用所引用时。并不能获取到该实例的对象。只有当该对象被回收时,才会收到通过并存入队列中。基本上用于操作直接内存来使用的。 可用于对一些重要对象的gc的监听。或者监听gc的频率(不如打印gc日志来的简单直观)。

以下 jvm参数 -Xmx20M。 当然也可以更小,主要是为了看gc 的效果。

/** * 虚拟引用 * 比较鸡肋,虚拟引用的对象,并不能get()出来。 而是直接操作 操作系统内存的。 * 虚拟引用的目标对象,被回收后,会存入队列中 * 需要新启一个线程监听该队列中,是否有数据。有数据 则 回收掉直接内存。 */public class MyPhantomReference {    private static  final List LIST = new LinkedList();    private static  final ReferenceQueue QUEUE = new ReferenceQueue();    public static void main(String[] args) {        PhantomReference  phantomReference = new PhantomReference(new MyPhantomReference(),QUEUE);        new Thread( () -> {            while(true){                LIST.add(new byte[1024*1024]);                try{                    Thread.sleep(1000);                }catch(Exception e){                    e.printStackTrace();                    Thread.currentThread().interrupt();                }                System.out.println(phantomReference.get());            }        }).start();        new Thread( () -> {            while(true){                Reference poll = QUEUE.poll();                if(poll != null){                  System.out.println("虚拟引用被jvm回收啦 ----" + poll);                }            }        }).start();        try{           Thread.sleep(500);        }catch(Exception e){            e.printStackTrace();        }    }}

感谢各位的阅读,以上就是"java中的引用有哪些"的内容了,经过本文的学习后,相信大家对java中的引用有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

对象 内存 年代 概念 内容 指针 示例 第一次 问题 学习 监听 年轻 重要 不够 参数 实例 数据 目标 空间 队列 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州淘业互联网络科技 深圳九邦互联网科技有限公司 中国互联网科技股 互联网品科技 互联网科技资迅 济南和联互联网科技有限公司 上海电发互联网科技有限公司 西藏七维空间互联网科技有限公司 广州慧亚互联网科技怎么样 互联网科技研发水平 民营互联网公司国防科技 西安小鹰速贷互联网科技有限公司 晋城互联网科技 工业互联网展湾科技股份有限公司 杭州披云加互联网科技有限公司 信承诺互联网科技有限公司 国产互联网科技公司 互联网科技收购价值 第三届互联网大会安防黑科技 互联网科技自媒体灵感 互联网通讯科技 互联网科技论文 互联网科技网站 互联网媒体平台算高科技产业 996高科技互联网公司 21世纪互联网科技成就 互联网科技融合创新 宁波跨境商互联网科技有限公司 互联网金融运营模式中的金融科技 互联网 科技节活动 微视频大赛
0