Java中弱引用和软引用的区别以及虚引用和强引用介绍

时间:2023-01-23 18:55:33 

知道弱引用和软引用的概念与如何使用它们是两码事,引用类在垃圾回收工作的过程中有重要作用。我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型。这正是Java中弱引用和软引用的主要区别。如果一个对象只有弱引用指向它,垃圾回收器会立即回收该对象,这是一种急切回收方式。相对的,如果有软引用指向这些对象,则只有在JVM需要内存时才回收这些对象。弱引用和软引用的特殊行为使得它们在某些情况下非常有用。例如:软引用可以很好的用来实现缓存,当JVM需要内存时,垃圾回收器就会回收这些只有被软引用指向的对象。而弱引用非常适合存储元数据,例如:存储ClassLoader引用。如果没有类被加载,那么也没有指向ClassLoader的引用。一旦上一次的强引用被去除,只有弱引用的ClassLoader就会被回收。这篇文章中我们将讲述不同类型的Java引用,例如:强引用(Strong Reference)和虚引用(PhantomReference)。

Java中弱引用VS软引用

Java中有如下四种类型的引用:

1.强引用(Strong Reference)
2.弱引用(WeakReference)
3.软引用(SoftReference)
4.虚引用(PhantomReference)

强引用是我们在编程过程中使用的最简单的引用,如代码String s=”abc”中变量s就是字符串对象”abc”的一个强引用。任何被强引用指向的对象都不能被垃圾回收器回收,这些对象都是在程序中需要的。弱引用使用java.lang.ref.WeakReference class 类来表示,你可以使用如下代码创建弱引用:


Counter counter = new Counter(); // strong reference - line 1
WeakReference<Counter> weakCounter = new WeakReference<Counter>(counter); //weak reference
counter = null; // now Counter object is eligible for garbage collection

现在只要你给强引用对象counter赋空值null,该对象就可以被垃圾回收器回收。因为该对象此时不再含有其他强引用,即使指向该对象的弱引用weakCounter也无法阻止垃圾回收器对该对象的回收。相反的,如果该对象含有软引用,Counter对象不会立即被回收,除非JVM需要内存。Java中的软引用使用java.lang.ref.SoftReference类来表示,你可以使用如下代码创建软引用:


Counter prime = new Counter(); // prime holds a strong reference – line 2
SoftReference soft = new SoftReference(prime) ; //soft reference variable has SoftReference to Counter Object created at line 2

prime = null; // now Counter object is eligible for garbage collection but only be collected when JVM absolutely needs memory

强引用置空之后,代码的第二行为对象Counter创建了一个软引用,该引用同样不能阻止垃圾回收器回收对象,但是可以延迟回收,与弱引用中急切回收对象不同。鉴于软引用和弱引用的这一区别,软引用更适用于缓存机制,而弱引用更适用于存贮元数据。另一个使用弱引用的例子是WeakHashMap,它是除HashMap和TreeMap之外,Map接口的另一种实现。WeakHashMap有一个特点:map中的键值(keys)都被封装成弱引用,也就是说一旦强引用被删除,WeakHashMap内部的弱引用就无法阻止该对象被垃圾回收器回收。

虚引用是java.lang.ref package包中第三种可用的引用,使用java.lang.ref.PhantomReference类来表示。拥有虚引用的对象可以在任何时候被垃圾回收器回收。和弱引用和软引用相似,你可以通过如下代码创建虚引用:


DigitalCounter digit = new DigitalCounter(); // digit reference variable has strong reference – line 3
PhantomReference phantom = new PhantomReference(digit); // phantom reference to object created at line 3

digit = null;

一旦移除强引用,第三行的DigitalCounter对象可以在任何时候被垃圾回收器回收。因为只有一个虚引用指向该对象,而虚引用无法阻止垃圾回收器回收对象。

除了了解弱引用、软引用、虚引用和WeakHashMap,还需要了解ReferenceQueue。在创建任何弱引用、软引用和虚引用的过程中你可以通过如下代码提供引用队列ReferenceQueue:


ReferenceQueue refQueue = new ReferenceQueue(); //reference will be stored in this queue for cleanup
DigitalCounter digit = new DigitalCounter();
PhantomReference<DigitalCounter> phantom = new PhantomReference<DigitalCounter>(digit, refQueue);

引用实例被添加在引用队列中,你可以再任何时候通过查询引用队列回收对象。一个对象的生命周期可以通过下图进行描述:

Java中弱引用和软引用的区别以及虚引用和强引用介绍
 

这就是Java中弱引用和软引用的区别。我们还学到了一些基本的引用类:弱引用、软引用、虚引用以及WeakHashMap和WeakHashMap。总之,合理的使用引用可以帮助垃圾回收器更好的管理Java内存。

标签:Java,弱引用,软引用,虚引用,强引用
0
投稿

猜你喜欢

  • intellij idea14打包apk文件和查看sha1值

    2022-05-25 13:18:37
  • java打印正弦曲线示例

    2022-05-04 00:48:56
  • C# ref and out的使用小结

    2021-12-19 22:35:40
  • Java使用OpenCV3.2实现视频读取与播放

    2023-11-23 06:14:02
  • 解决bufferedReader.readLine()读到最后发生阻塞的问题

    2022-07-15 06:05:38
  • 基于hibernate框架在eclipse下的配置方法(必看篇)

    2022-11-09 20:30:26
  • Android开发实例之多点触控程序

    2023-06-19 00:25:09
  • 老生常谈java中cookie的使用

    2023-11-11 04:37:59
  • Android Bitmap和Drawable的对比

    2021-11-16 06:03:41
  • 基于Android6.0实现弹出Window提示框

    2023-01-12 05:23:25
  • SpringBoot设置编码UTF-8的两种方法

    2022-05-04 00:09:08
  • Java超详细教你写一个银行存款系统案例

    2022-01-04 22:33:59
  • C#中OpenCvSharp 通过特征点匹配图片的方法

    2023-07-14 08:10:55
  • Java实现堆排序(大根堆)的示例代码

    2023-09-13 15:24:01
  • Spring 实现excel及pdf导出表格示例

    2023-12-21 04:17:32
  • Maven搭建springboot项目的方法步骤

    2022-08-08 09:50:09
  • Android隐藏标题栏及解决启动闪过标题的实例详解

    2023-10-10 12:18:12
  • Spring Boot mybatis-config 和 log4j 输出sql 日志的方式

    2021-05-31 22:13:20
  • Java 实战范例之线上婚纱摄影预定系统的实现

    2021-08-08 14:19:42
  • Java之Algorithm_analysis案例详解

    2022-03-07 01:34:50
  • asp之家 软件编程 m.aspxhome.com