当在 Java 2 平台中首次引入 java.lang.ref 包,其中包含 SoftReference 、 WeakReference 和 PhantomReference 三个引用类,引用类的主要功能就是能够引用仍可以被垃圾收集器回收的对象。在引入引用类之前,我们只能使用强引用(strong reference)。举例来说,下面一行代码显示的就是强引用 obj :

Object obj = new Object();

obj 这个引用将引用堆中存储的一个对象。只要 obj 引用还存在,垃圾收集器就永远不会释放用来容纳该对象的存储空间。

当 obj 超出范围或被显式地指定为 null 时,垃圾收集器就认为没有对这个对象的其它引用,也就可以收集它了。然而您还需要注意一个重要的细节:仅凭对象可以被收集并不意味着垃圾收集器的一次指定运行就能够回收它。由于各种垃圾收集算法有所不同,某些算法会更频繁地分析生存期较短的对象,而不是较老、生存期较长的对象。因此,一个可供收集的对象可能永远也不会被回收。如果程序在垃圾收集器释放对象之前结束,这种情况就可能会出现。因此,概括地说,您永远无法保证可供收集的对象总是会被垃圾收集器收集。

这些信息对于您分析引用类是很重要的。由于垃圾收集有着特定的性质,所以引用类实际上可能没有您原来想像的那么有用,尽管如此,它们对于特定问题来说还是很有用的类。软引用(soft reference)、弱引用(weak reference)和虚引用(phantom reference)对象提供了三种不同的方式来在不妨碍收集的情况下引用堆对象。每种引用对象都有不同的行为,而且它们与垃圾收集器之间的交互也有所不同。此外,这几个新的引用类都表现出比典型的强引用“更弱”的引用形式。而且,内存中的一个对象可以被多个引用(可以是强引用、软引用、弱引用或虚引用)引用。在进一步往下讨论之前,让我们来看看一些术语:

  • 强可及对象(strongly reachable):可以通过强引用访问的对象。
  • 软可及对象(softly reachable):不是强可及对象,并且能够通过软引用访问的对象。
  • 弱可及对象(weakly reachable):不是强可及对象也不是软可及对象,并且能够通过弱引用访问的对象。
  • 虚可及对象(phantomly reachable):不是强可及对象、软可及对象,也不是弱可及对象,已经结束的,可以通过虚引用访问的对象。
  • 清除:将引用对象的 referent 域设置为 null ,并将引用类在堆中引用的对象声明为 可结束的。

SoftReference 类

SoftReference 类的一个典型用途就是用于内存敏感的高速缓存。 SoftReference 的原理是:在保持对对象的引用时保证在 JVM 报告内存不足情况之前将清除所有的软引用。关键之处在于,垃圾收集器在运行时可能会(也可能不会)释放软可及对象。对象是否被释放取决于垃圾收集器的算法以及垃圾收集器运行时可用的内存数量。

WeakReference 类

WeakReference 类的一个典型用途就是规范化映射(canonicalized mapping)。另外,对于那些生存期相对较长而且重新创建的开销也不高的对象来说,弱引用也比较有用。关键之处在于,垃圾收集器运行时如果碰到了弱可及对象,将释放 WeakReference 引用的对象。然而,请注意,垃圾收集器可能要运行多次才能找到并释放弱可及对象。

PhantomReference 类

PhantomReference 类只能用于跟踪对被引用对象即将进行的收集。同样,它还能用于执行 pre-mortem 清除操作。PhantomReference 必须与 ReferenceQueue 类一起使用。需要 ReferenceQueue 是因为它能够充当通知机制。当垃圾收集器确定了某个对象是虚可及对象时, PhantomReference 对象就被放在它的 ReferenceQueue 上。将PhantomReference 对象放在 ReferenceQueue 上也就是一个通知,表明 PhantomReference 对象引用的对象已经结束,可供收集了。这使您能够刚好在对象占用的内存被回收之前采取行动。

Java中引用类 strong reference .SoftReference 、 WeakReference 和 PhantomReference的区别的更多相关文章

  1. Java 中File类的createNewFile()与createTempFile(), delete和deleteOnExit区别

    1. Java 中File类的createNewFile()与createTempFile()的区别 最近,在看代码时看到了一个方法, File.createTempFile() ,由此联想到File ...

  2. Java中String类new创建和直接赋值字符串的区别

    转自:https://blog.csdn.net/a986410589/article/details/52454492 方式一:String a = “aaa” ; 方式二:String b = n ...

  3. Java核心技术-高级特性(2)- SoftReference, WeakReference and PhantomReference

    Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类.这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 Ja ...

  4. JAVA中的类和接口

    1.类: 类是具有相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分.在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属 ...

  5. 【JAVA零基础入门系列】Day11 Java中的类和对象

    今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...

  6. 第四节:详细讲解Java中的类和面向对象思想

    前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...

  7. Java中Optional类的使用

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  8. 细说java中的类

    前言 最近在学习<java编程思想> 学到了内部类 类不就是class吗 天天用 还能讲出花来了不成... 其实不然,在java中,类的种类和使用方式多种多样,花样繁多.其中主要有 普通类 ...

  9. Java中Class类详解、用法及泛化

    Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI.这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方 ...

随机推荐

  1. Gitlab的Gravatar头像无法显示的问题

    通过gitlab搭建的git仓库,由于Gravatar被墙了,导致Gravatar头像无法显示.总觉得怪怪的. 社区版gitlab解决办法: vi /var/opt/gitlab/gitlab-rai ...

  2. CEF3开发者系列之外篇——IE中JS与C++交互

    使用IE内核开发客户端产品,系统和前端页面之间的交互,通常给开发和维护带来很大的便利性.但操作系统和前端之间的交互却是比较复杂的.具体来说就是脚本语言和编译语言的交互.在IE内核中html和css虽然 ...

  3. PHP写时复制, 变量复制和对象复制不同!!!

    2016年3月18日 15:09:28 星期五 一直以为PHP对象也是写时复制....... 其实: PHP的变量是写时复制, 对象是引用的 写时复制: $a = $b; 如果$b的内容不改变, $a ...

  4. Metro各种流转换

    Ibuffer转byte[] ,(int)buffer.Length); Byte[]转Ibuffer WindowsRuntimeBufferExtensions.AsBuffer(bytes,,b ...

  5. STL:原地归并排序模板(InplaceMergeSort)

    原理:就是在归并排序上改进,以时间复杂度换空间复杂度,利用元素反转完成排序 具体过程如下: 具体操作看代码吧,应该没什么难度,主要是reverse要反转三次 typedef int Position; ...

  6. 【leetcode】Merge Two Sorted Lists(easy)

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  7. 【Git】笔记3

    来源:廖雪峰 远程仓库 远程仓库采用github 准备工作:创建远程仓库 1.创建一个github账号 2.在本地设置ssh,获取/home/user/.ssh/id_rsa.pub内容 3.在git ...

  8. Qt 添加启动项

    QString application_name = QApplication::applicationName(); QSettings *settings = new QSettings(&quo ...

  9. 关闭Eclipse的控制台console自动跳出

    一.背景 在eclipse中进行开发,尤其是在后台有项目运行的时候,当有log或者错误需要打印到console中时,控制台就会被自动弹出,恰好这时候你又在编写代码,就会感觉瞬间想杀人,下面我们就来分享 ...

  10. [网络流24题]餐巾(cogs 461)

    [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分 ...