JVM 引用

本文将介绍 Java 中的引用类型,它是 Java 中的指针。

一、什么是引用?

引用,reference,用于定位对象。

二、通过引用访问对象

在《Java 虚拟机规范》中,只规定了引用指向对象,并没有定义引用应该通过什么方式去定位、访问具体对象。

当前的主流访问方式有以下两种:

  • 句柄访问:

    在堆中划分出一块区域作为句柄池。首先由对象引用定位到句柄,然后可以根据句柄上的两个指针分别定位到对象实例数据和对象类型信息。

  • 指针访问:

    由对象引用可以直接定位到对象实例数据,然后可以根据其中的指针访问到对象类型数据。

简单来说,引用既可以是指向 “指向对象的句柄” 的指针,也可以是直接指向对象的指针。

三、引用的不同级别

在 JDK 1.2 版本以前,引用的类型只有一种,即 reference。在这种情况下,对象只有已被引用和未被引用两种状态。

为了描述这样一种对象:当内存空间足够时,保留;当内存空间紧张时,可以清除。Java 对引用的概念进行了扩充,将引用分为四个级别,如下:

  • 强引用 Strongly Reference:
    • 对应最传统的引用定义,即程序代码中普遍存在的引用赋值,例如 Obj obj = new Obj()
    • 无论任何情况,只要强引用存在,对象便不会被回收
  • 软引用 Soft Reference:
    • 用于描述 “有用但非必须” 的对象
    • 在系统将要发生内存溢出异常时,会将软引用对应的对象列入回收范围中,进行回收,如果回收后内存依旧不够,才会抛出内存溢出异常
  • 弱引用 Weak Reference:
    • 用于描述 “有用但非必须” 的对象,弱于软引用
    • 当垃圾收集器开始工作时,无论内存是否充足,都会将弱引用对应的对象回收掉,弱引用对应的对象只能生存到下一次垃圾回收
  • 虚引用 Phantom Reference:
    • 又称 “幽灵引用”、”幻影引用”
    • 一个对象是否有虚引用,不影响它的生存时间
    • 无法通过虚引用访问到对象
    • 虚引用的唯一作用是在对象被回收时收到一个系统通知

参考

  • 深入理解 Java 虚拟机