JVM 四种引用和使用场景

简介: 在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,Java 4种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用 > 虚引用。

在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,Java 4种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用 > 虚引用。

1、强引用

功能:使用最普遍的引用,可以直接访问目标对象。一个对象如果具有强引用,那么垃圾回收器绝不会回收它,即使当内存不足时,VM宁愿抛出内存不足的异常,也不会去回收这些对象。(可能导致内存泄露)

使用场景:我们平常大部分使用的场景都是使用了强引用,比如new创建对象,反射获得一个对象等。

2、软引用

功能: 描述一些还有用但非必需的对象,如果一个对象只具有软引用,则内存空间足够时,垃圾回收器就不会去回收它;如果内存空间不足时,就会回收这些对象的内存。只要GC没有回收它,该对象就可以被程序正常使用和访问。JDK1.2之后,提供了SoftReference类来实现软引用。软引用可以用来实现内存敏感的高速缓存。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果这个软引用所引用的对象被垃圾回收器回收,Java虚拟机就会将这个软引用加入到关联的引用队列中。

使用场景: 适用于网页缓存、图片缓存,防止内存溢出,在内存充足的时候,缓存对象会一直存在,在内存不足的时候,缓存对象占用的内存会被垃圾收集器回收。

3、弱引用

功能: 也是描述还有用但非必需的对象,与软引用相比,具有弱引用的对象的生命周期更短,被弱引用关联的对象只能生存到下一次GC发生之前,垃圾回收器在扫描的时候,一旦发现只具有弱引用的对象,不管内存空间是否足够,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,不一定会很快发现那些只具有弱引用的对象。JDK1.2之后,提供了WeakReference类来实现弱引用。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果这个弱引用所引用的对象被垃圾回收器回收,Java虚拟机就会将这个弱引用加入到关联的引用队列中。

使用场景: 弱引用用于生命周期更短的,对内存更敏感的场景中,比如占用内存很大的Map,java api中就提供了WeakHashMap使用,就会使得大Map被及时清理掉。

4、虚引用

功能:也称为幽灵引用或者幻影引用,最弱的一种引用关系,形同虚设,与其他几种引用都不同。虚引用并不会决定对象的生命周期,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。JDK1.2之后,提供了PhantomReference类来实现软引用。

一个对象设置虚引用关联的唯一目的就是在这个对象被垃圾收集器回收时收到一个系统通知。可以利用虚引用来做一些对象销毁前的操作,如资源释放等。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

使用场景: 判断一个对象是否被垃圾回收了,跟踪对象被垃圾回收回收的活动。一般可以通过虚引用达到回收一些非java内的一些资源比如堆外内存的行为。例如:在 DirectByteBuffer 中,会创建一个 PhantomReference 的子类Cleaner的虚引用实例用来引用该 DirectByteBuffer 实例,Cleaner 创建时会添加一个 Runnable 实例,当被引用的 DirectByteBuffer 对象不可达被垃圾回收时,将会执行 Cleaner 实例内部的 Runnable 实例的 run 方法,用来回收堆外资源。

相关文章
|
4月前
|
算法 安全 Java
Java面试题:解释JVM中的堆内存分代收集策略,并讨论年轻代和老年代的特点,描述Java中的线程池,并解释线程池的优点,解释Java中的`volatile`关键字的作用和使用场景
Java面试题:解释JVM中的堆内存分代收集策略,并讨论年轻代和老年代的特点,描述Java中的线程池,并解释线程池的优点,解释Java中的`volatile`关键字的作用和使用场景
46 0
|
6月前
|
存储 缓存 算法
深入浅出JVM(十四)之内存溢出、泄漏与引用
深入浅出JVM(十四)之内存溢出、泄漏与引用
|
6月前
|
存储 缓存 Java
JVM 引用
JVM中所有的引用类型,都是抽象类java.lang.ref.Reference的子类,这个类的主要方法为get()方法。
|
存储 缓存 算法
GC面临的困境,JVM是如何解决跨代引用的?
前面我们讲了可达性分析和根节点枚举,介绍完了GC的前置工作,下面开始讲GC的工作过程。
160 0
GC面临的困境,JVM是如何解决跨代引用的?
|
存储 算法 Java
JVM 收集算法 垃圾收集器 元空间 引用
JVM 收集算法 垃圾收集器 元空间 引用
106 0
|
存储 缓存 算法
jvm之4种引用的解读
jvm之4种引用的解读
|
缓存 算法 Java
《深入理解Java虚拟机》读书笔记(四)--GC的回收条件及Java对象的引用
《深入理解Java虚拟机》读书笔记(四)--GC的回收条件及Java对象的引用
234 0
|
Java
JVM垃圾回收——五种引用
如果在垃圾回收时发现内存不足,在回收软引用所指向的对象时,软引用本身不会被清理
144 0
JVM垃圾回收——五种引用
|
存储 缓存 Java
JVM内存结构详细总结(结合自身使用经历介绍各个知识点使用场景)
如图JVM运行时数据区域划分为以下6个主要部分:①程序计数器,②虚拟机栈,③本地方法栈,④虚拟机堆,⑤方法区,⑥直接内存,下面对6个部分详细总结,希望可以对路过的朋友有所帮助。
124 0
JVM内存结构详细总结(结合自身使用经历介绍各个知识点使用场景)
玩转JVM中的对象及引用:从创建到引用到分配和优化策略
类加载检查 当Java虚拟机遇到一条new指令的时候,它会先去运行时常量池中寻找new的类的符号引用,并且检查这个符号引用所代表的类是否已经被加载、解析、初始化过。如果没有即需要进行相应的类加载过程。