一. 简介

在看ThreadLocal源码的时候,其中嵌套类ThreadLocalMap中的Entry继承了WeakReferenc,为了能搞清楚ThreadLocal,只能先了解下了WeakReferenc(是的,很多时候为了搞清楚一个东西,不得不往上追好几层,先搞清楚其所依赖的东西。)
下面进入正题,WeakReference如字面意思,弱引用, 当一个对象仅仅被weak reference(弱引用)指向, 而没有任何其他strong reference(强引用)指向的时候, 如果这时GC运行, 那么这个对象就会被回收,不论当前的内存空间是否足够,这个对象都会被回收。

二. 认识WeakReference类

WeakReference继承Reference,其中只有两个构造函数:

public class WeakReference<T> extends Reference<T> {public WeakReference(T referent) {super(referent);}public WeakReference(T referent, ReferenceQueue<? super T> q) {super(referent, q);}}
  • WeakReference(T referent):referent就是被弱引用的对象(注意区分弱引用对象和被弱引用的对象,弱引用对象是指WeakReference的实例或者其子类的实例),比如有一个Apple实例apple,可以如下使用,并且通过get()方法来获取apple引用。也可以再创建一个继承WeakReference的类来对Apple进行弱引用,下面就会使用这种方式。
WeakReference<Apple> appleWeakReference = new WeakReference<>(apple);
Apple apple2 = appleWeakReference.get();
  • WeakReference(T referent, ReferenceQueue<? super T> q):与上面的构造方法比较,多了个ReferenceQueue,在对象被回收后,会把弱引用对象,也就是WeakReference对象或者其子类的对象,放入队列ReferenceQueue中,注意不是被弱引用的对象,被弱引用的对象已经被回收了。

三. 使用WeakReference

下面是使用继承WeakReference的方式来使用软引用,并且不使用ReferenceQueue。

简单类Apple

package io.github.brightloong.lab.reference;/*** Apple class** @author BrightLoong* @date 2018/5/25*/
public class Apple {private String name;public Apple(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}/*** 覆盖finalize,在回收的时候会执行。* @throws Throwable*/@Overrideprotected void finalize() throws Throwable {super.finalize();System.out.println("Apple: " + name + " finalize。");}@Overridepublic String toString() {return "Apple{" +"name='" + name + '\'' +'}' + ", hashCode:" + this.hashCode();}
}

继承WeakReference的Salad

package io.github.brightloong.lab.reference;import java.lang.ref.WeakReference;/*** Salad class* 继承WeakReference,将Apple作为弱引用。* 注意到时候回收的是Apple,而不是Salad** @author BrightLoong* @date 2018/5/25*/
public class Salad extends WeakReference<Apple> {public Salad(Apple apple) {super(apple);}
}

Clent调用和输出

package io.github.brightloong.lab.reference;import java.lang.ref.WeakReference;/*** Main class** @author BrightLoong* @date 2018/5/24*/
public class Client {public static void main(String[] args) {Salad salad = new Salad(new Apple("红富士"));//通过WeakReference的get()方法获取AppleSystem.out.println("Apple:" + salad.get());System.gc();try {//休眠一下,在运行的时候加上虚拟机参数-XX:+PrintGCDetails,输出gc信息,确定gc发生了。Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}//如果为空,代表被回收了if (salad.get() == null) {System.out.println("clear Apple。");}}
}

输出如下:

Apple:Apple{name='红富士'}, hashCode:1846274136
[GC (System.gc()) [PSYoungGen: 3328K->496K(38400K)] 3328K->504K(125952K), 0.0035102 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC (System.gc()) [PSYoungGen: 496K->0K(38400K)] [ParOldGen: 8K->359K(87552K)] 504K->359K(125952K), [Metaspace: 2877K->2877K(1056768K)], 0.0067965 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Apple: 红富士 finalize。
clear Apple。

ReferenceQueue的使用

package io.github.brightloong.lab.reference;import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;/*** Client2 class** @author BrightLoong* @date 2018/5/27*/
public class Client2 {public static void main(String[] args) {ReferenceQueue<Apple> appleReferenceQueue = new ReferenceQueue<>();WeakReference<Apple> appleWeakReference = new WeakReference<Apple>(new Apple("青苹果"), appleReferenceQueue);WeakReference<Apple> appleWeakReference2 = new WeakReference<Apple>(new Apple("毒苹果"), appleReferenceQueue);System.out.println("=====gc调用前=====");Reference<? extends Apple> reference = null;while ((reference = appleReferenceQueue.poll()) != null ) {//不会输出,因为没有回收被弱引用的对象,并不会加入队列中System.out.println(reference);}System.out.println(appleWeakReference);System.out.println(appleWeakReference2);System.out.println(appleWeakReference.get());System.out.println(appleWeakReference2.get());System.out.println("=====调用gc=====");System.gc();try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("=====gc调用后=====");//下面两个输出为null,表示对象被回收了System.out.println(appleWeakReference.get());System.out.println(appleWeakReference2.get());//输出结果,并且就是上面的appleWeakReference、appleWeakReference2,再次证明对象被回收了Reference<? extends Apple> reference2 = null;while ((reference2 = appleReferenceQueue.poll()) != null ) {//如果使用继承的方式就可以包含其他信息了System.out.println("appleReferenceQueue中:" + reference2);}}
}

结果输出如下:

=====gc调用前=====
java.lang.ref.WeakReference@6e0be858
java.lang.ref.WeakReference@61bbe9ba
Apple{name='青苹果'}, hashCode:1627674070
Apple{name='毒苹果'}, hashCode:1360875712
=====调用gc=====
Apple: 毒苹果 finalize。
Apple: 青苹果 finalize。
=====gc调用后=====
null
null
appleReferenceQueue中:java.lang.ref.WeakReference@6e0be858
appleReferenceQueue中:java.lang.ref.WeakReference@61bbe9baProcess finished with exit code 0

可以看到在队列中(ReferenceQueue),调用gc之前是没有内容的,调用gc之后,对象被回收了,并且弱引用对象appleWeakReference和appleWeakReference2被放入了队列中。

关于其他三种引用,强引用、软引用、虚引用,可以参考[转]Java 的强引用、弱引用、软引用、虚引用 - gudi - 博客园

弱引用(WeakReference)初识相关推荐

  1. Android 弱引用 (WeakReference)的使用

    1 弱引用 (WeakReference) 弱引用对象,这些对象不会阻止对其引用对象进行终结,终结和回收.弱引用最常用于实现规范化映射.假设垃圾收集器在某个时间点确定对象是弱可到达的.到那时,它将自动 ...

  2. 弱引用WeakReference和软引用SoftReference

    在Java1.2中我们可以发现一个java.lang.ref包,在这个包中我们可以发现有关引用的知识,比如WeakReference弱引用和SoftReference强引用. 弱引用(WeakRefe ...

  3. 弱引用WeakReference作用与使用场景

    文章目录 1. Demo 2. 使用场景 在分析threadLocal源码时,发现有使用弱引用WeakReference,在之前总结GC的时候,也曾简单介绍java引用类型(<jvm GC算法类 ...

  4. Android学习笔记之SoftReference软引用,弱引用WeakReference

    SoftReference可以用于bitmap缓存 WeakReference 可以用于handler 非静态内部类和匿名内部类容易造成内存泄漏 private Handler mRemoteHand ...

  5. SAP ABAP和Java里的弱引用(WeakReference)和软引用(SoftReference)

    Jerry前一篇文章 SAP ABAP一组关键字 IS BOUND, IS NOT INITIAL和IS ASSIGNED的用法辨析 介绍了在ABAP里判断引用变量是否包含了一个有效引用的关键字:IS ...

  6. 弱引用WeakReference

    WeakReference是Java语言规范中为了区别直接的对象引用(程序中通过构造函数声明出来的对象引用)而定义的另外一种引用关系.WeakReference标志性的特点是:reference实例不 ...

  7. android 软引用intent对象,Android中的软引用(SoftRefrerence)和弱引用(WeakReference)

    在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面 ...

  8. Java中的弱引用WeakReference详解

    最近再看ThreadLocal源码,其中内部类ThreadLocalMap中的Entry类继承了WeakReference,其表示key的ThreadLocal对象是通过弱应用指向,如果外部没有强引用 ...

  9. Java弱引用(WeakReference)的理解与使用

    转:https://blog.csdn.net/zmx729618/article/details/54093532 看到篇帖子, 国外一个技术面试官在面试senior java developer的 ...

  10. Java弱引用(WeakReference)

    最近在看ThreadLocal,看到WeakReference,学习一下 ExecutorService executorService = Executors.newCachedThreadPool ...

最新文章

  1. 第一章 介绍-机器学习老师板书-斯坦福吴恩达教授
  2. 登录功能(token)
  3. c++指针引用导出文件
  4. leetcode 171. Excel表列序号
  5. C++:求区间内最大的因子和
  6. python中验证码连通域分割的方法详解
  7. Android重力感应实现方式简介
  8. PHP 文件下载 header设置
  9. iso硬盘安装 凤凰os_Windows硬盘安装凤凰系统(Phoenix OS)可以用电脑玩吃鸡啦~
  10. android显示动态图片,android显示gif图
  11. 一文看懂AutoML
  12. 20种银河科幻风格ps字体样式
  13. 亲自动手从源码 构建 Groovy 2.3.8 发布包
  14. RocketMQ消息发送源码解析
  15. 上海航芯|推出基于ACX200T的V2X解决方案
  16. 解决图片处理后旋转问题
  17. 可以删除电脑文件的c语言程序,win7电脑c盘都有哪些文件可以删除
  18. Unable to load DLL 'xxx.dll': 找不到指定的模块。 (Exception from HRESULT: 0x8007007E)
  19. Win获取本地SVN帐号密码
  20. PADS-电阻、电容、电感PCB封装

热门文章

  1. Android 实现SKU选择通用方式
  2. linux 文件系统 panic,Linux kernel panic解决方法
  3. Android 截取指定号码的短信 并且不让系统获取短信通知用户
  4. mysql之关联更新(update join,用b表更新a表记录)
  5. 从头认识Spring-1.14 SpEl表达式(3)-SpEl表达式的两个坑:Bean的顺序与Bean的toString方法
  6. R720服务器打开Linux,戴尔服务器(R720\R820)在linux6.4下双网卡绑定具体步骤
  7. 【Unity】如何删除不要的Tile Palette(瓦片地图)(遇到新的问题就继续更新2021.4.29)
  8. 手把手教你使用Python抓取QQ音乐数据(第一弹)
  9. 基于java的oa协同办公系统_基于JAVA的OA系统的制作毕业设计论文
  10. 运气和技术的另类平衡————对大逃杀及战棋类游戏大热的原因思考(正片)