在 Java 语言中,除了原始数据类型的变量,其他所有都是所谓的引用类型,指向各种不同的对象。理解引用对于掌握 Java 对象生命周期和 JVM 内部相关机制非常有帮助。不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响。
引用出现的根源是由于GC内存回收的基本原理-GC回收内本质上是回收对象,而目前比较流行的回收算法是可达性分析算法,从GC Roots开始按照一定的逻辑判断一个对象是否可达,不可达的话就说明该对象已死(除此之外另外一种常见的算法就是引用计数法,但是这种算法不能解决相互引用的问题)。基于此Java向用户提供了四种可用的引用:强引用、软引用、弱引用和幻象引用,同时还提供了一种不可被使用的引用-FinalReference,这个引用是和析构函数密切相关的。
强引用是开发者通过new的方式创建的,其他几种引用Java提供了相应的类:SoftReference、WeakReference、PlantomReference。如果你去查看源码,你会发现这个类实现的核心是Reference和ReferenceQueue(引用队列)两个类,而且这两个类也特别的简单。
Java世界泰山北斗级大作《Thinking In Java》切入Java就提出“Everything is Object”。在Java这个充满Object的世界中,Reference是一切谜题的根源,所有的故事都是从这里开始的。
Reference类似一个链表结构,通过创建一个守护线程来执行对应引用的清除、Cleaner.clean、以及引用的入队操作。
ReferenceQueue是指定了引用队列的一些具体操作,简单来说它是一个链表结构,并提供了一些基本的链表操作。而除了强引用外其他的都是继承于此,通过这样的类约束了引用的相关内容,便于和GC进行交互。
这几类引用的区别如下:
1、强引用是通过new创建的对象引用。只有当GC明确判断该引用无效时才会回收相应的引用对象,即使抛出OOM。
2、软引用是当GC检测到继续创建对象会导致OOM时会进行一次垃圾回收,这次回收会将软引用回收以防抛出异常,根据这样的特点该引用常用来被当做缓存使用。图片缓存框架中,“内存缓存”中的图片是以这种引用来保存,使得JVM在发生OOM之前,可以回收这部分缓存。在静态内部类中,经常会使用虚引用。例如,一个类发送网络请求,承担callback的静态内部类,则常以虚引用的方式来保存外部类(宿主类)的引用,当外部类需要被JVM回收时,不会因为网络请求没有及时回来,导致外部类不能被回收,引起内存泄漏。
3、虚引用是那些如果引用未被使用,就会在最近的一次GC时被回收。例如Java的ThreadLocal与动态代理都是基于这样的一个引用实现的,一般针对那些比较敏感的数据。
4、幻象引用是针对那些已经执行完析构函数之后,仍然需要再执行一些其他操作的对象,比如资源对象的关闭就可以用到该引用。
除了幻象引用(因为 get 永远返回 null),如果对象还没有被销毁,都可以通过 get 方法获取原有对象。这意味着,利用软引用和弱引用,我们可以将访问到的对象,重新指向强引用,也就是人为的改变了对象的可达性状态!所以,对于软引用、弱引用之类,垃圾收集器可能会存在二次确认的问题,以保证处于弱引用状态的对象,没有改变为强引用。
如果我们错误的保持了强引用(比如,赋值给了 static 变量),那么对象可能就没有机会变回类似弱引用的可达性状态了,就会产生内存泄漏。所以,检查弱引用指向对象是否被垃圾收集,也是诊断是否有特定内存泄漏的一个思路,如果我们的框架使用到弱引用又怀疑有内存泄漏,就可以从这个角度检查。
相关推荐
从Java SE2开始,Java引入了四种不同类型的引用:强引用、软引用、弱引用和虚引用,它们各自具有不同的特点和用途,有助于程序员更精细地控制对象的生命周期,并优化垃圾回收过程。 1. 强引用(Strong Reference) ...
本文将深入探讨强引用、软引用、弱引用以及幻象引用这四种引用类型,以及它们与垃圾收集的关系。 1. **强引用(Strong Reference)**: - 强引用是Java中最常见的引用类型,它代表了一个对象的直接访问路径。只要...
Java提供了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用(幻象引用),每种引用类型在内存管理中有不同的作用。 1. **强引用(Strong Reference)** - 强引用是最常见的引用类型,即通常的变量赋值。...
一个对象是否有幻象引用的存在完全不会对其生存时间构成影响,也无法通过幻象引用来获取到对象实例。为一个对象设置幻象引用必须提供一个引用队列(ReferenceQueue)作为参数。当垃圾回收器准备回收一个对象时,如果...
在 Java 中,对象的引用方式有四种:强引用、软引用、弱引用和幻象引用。这些引用方式的使用场景和特点是不同的,下面我们详细介绍每种引用方式的特点和使用场景。 强引用 强引用是最常用的引用方式,通过 new ...
软引用是相对于强引用的一种弱化形式,它在内存管理中起到一种平衡的作用。当一个对象仅由软引用指向时,垃圾回收器会在内存不足时才会考虑回收这些对象。这意味着软引用可以提供一定的内存保护,防止因内存不足引发...
4. 虚引用(Phantom Reference):也称为幽灵引用或幻象引用,它是最弱的一种引用关系,虚引用对象的存在不会阻止对象被垃圾回收,但它可以提供一个回调机制,让你在对象被回收之前做一些清理工作。 解决内存泄漏的...
弱引用和软引用在内存不足时能帮助系统更有效地回收资源,而幻象引用则允许在对象即将被彻底回收前执行必要的清理操作。理解并灵活运用这些引用类型,能够帮助开发者编写出更加高效、内存友好的Java程序。
9. Java 四种引用类型:强引用、软引用、弱引用、幻象引用 10. 悲观锁和乐观锁的区别 二、Android 开发 1. Android 四大组件:Activity、Service、BroadcastReceiver、ContentProvider 2. Fragment 的生命周期和...
- **强引用**:最常见的引用,只要强引用存在,垃圾收集器就不会回收对象。 - **软引用**:当内存不足时,垃圾收集器会回收软引用的对象。 - **弱引用**:垃圾收集器在任何时候都可以回收弱引用对象。 - **虚...
2. **徐喷以烟**:这个动作是作者为了让蚊子在烟雾中飞舞,模拟云中鹤舞的场景,进一步增强幻象的真实感。 3. **以虫蚁为兽,以丛草为林,以土砾凸者为丘,凹者为壑**:这些描述展示了作者如何利用想象力将微小的...
- (1)使用了列数字和作比较的说明方法,通过具体的数值和比较(紫色光散射是红色光的10倍以上)来说明短波光的散射效果。 - (2)运用了打比方和列数字的说明方法,将日落时的太阳比喻为“巨大的玉盘”,并列举数据...