JVM GC Roots 及强引用 软引用 弱引用 虚引用

对象已死吗

在堆里面几乎存放着 Java 世界所有的对象实例,垃圾收集器在对对象回收前,第一步就是要确定这些对象中哪些还“存活”着,哪些已经“死去”(即不能再被任何途径使用的对象)。

GC Roots

《深入理解JVM》原文:
在主流的商用程序语言中(Java和C#),都是使用可达性分析算法判断对象是否存活的。这个算法的基本思路就是通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
如下图所示,obj 1、2、3、4、5 是存活的对象。而obj 6、7、8 虽然有相互关联,但是他们到 gc roots 是不可达的,所以他们会被判定为可回收的对象。

一般来说 GC Roots 包含以下几个:

  1. 虚拟机栈(栈桢中的本地变量表)中的引用的对象
  2. 方法区中的类静态属性引用的对象
  3. 方法区中的常量引用的对象
  4. 本地方法栈中JNI(Native方法)的引用的对象

gc

谈谈引用

在 jdk 1.2 之前,Java 中的引用的定义很传统:如果 reference 类型的数据中存储的数值代表的是另外一块内存地址的起始地址,就称这块内存代表着一个引用。这种定义很纯粹,但是太过狭隘,一个对象在这种定义下只有被引用和不被引用两种状态,对于如何描述一些“食之无肉,弃之可惜”的对象显得无能为力。我们希望有这样一类对象:当内存空间还足够时,则保留在内存之中;如果内存空间在垃圾回收后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景。

在 jdk 1.2 之后,Java 对引用概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用强度一次逐渐减弱。
4 种引用的强度:强 > 软 > 弱 > 虚

强引用

强引用就是指在程序代码之中普遍存在的,类似“Object obj = new Objective();”这类的引用,只要强引用还存在,垃圾收集器永远不会回收被引用的对象。

软引用

软引用是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统即将发生内存溢出异常前,将会把这些对象列进回收范围进行二次回收。如果这次回收完还是没有足够的内存,才会抛出内存溢出异常。在 jdk 1.2 之后提供了 SoftReference 类来实现软引用。
应用场景:这种机制和缓存的需求不谋而合,可以在一些缓存类数据的场景应用。

弱引用

弱引用也是用来描述非必需的对象,但它的强度比软引用更弱一些,被引用的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在 jdk 1.2 后,提供了 WeakReference 类来实现弱引用。

虚引用

虚引用也被称为幽灵引用或幻影引用,它是最弱的一种引用关系。一个对象有虚引用存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。对一个对象设置虚引用关联的唯一目的就是能在这个对象被收集后得到一个系统通知。在 jdk 1.2 之后,提供了 PhantomReference 类来实现虚引用。

猜你喜欢

转载自blog.csdn.net/wandou9527/article/details/107530332