一. 简介

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;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

import java.lang.ref.WeakReference;/*** Salad class* 继承WeakReference,将Apple作为弱引用。* 注意到时候回收的是Apple,而不是Salad*/
public class Salad extends WeakReference<Apple> {public Salad(Apple apple) {super(apple);}
}

Clent调用和输出

import java.lang.ref.WeakReference;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:474675244
Apple:红富士 finalize。
clear Apple。

ReferenceQueue的使用

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;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@5e91993f
java.lang.ref.WeakReference@1c4af82c
Apple{name='青苹果'}, hashCode:932583850
Apple{name='毒苹果'}, hashCode:212628335
=====调用gc=====
Apple:毒苹果 finalize。
Apple:青苹果 finalize。
=====gc调用后=====
null
null
appleReferenceQueue中:java.lang.ref.WeakReference@1c4af82c
appleReferenceQueue中:java.lang.ref.WeakReference@5e91993f

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

关于其他三种引用,强引用、软引用、虚引用,可以参考:
    Carson带你学Java:深入解析引用类型-强、软、弱、虚

关于 Java 中的 WeakReference相关推荐

  1. Java中的 WeakReference 和 SoftReference

    我们知道Java语言中没有指针,取而代之的是引用reference.Java中的引用又可以分为四种:强引用,弱引用(WeakReference),软引用(SoftReference),虚引用(Phan ...

  2. 关于Java中的WeakReference类的笔记(弱引用)

    前言 今天在看ThreadLocal源码的时候,其中内部类ThreadLocalMap中的Entry继承了WeakReferenc,为了能搞清楚ThreadLocal,只能先了解下了WeakRefer ...

  3. 关于Java中的WeakReference

    WeakReference 阅读原文请访问我的博客BrightLoong's Blog 一. 简介 在看ThreadLocal源码的时候,其中嵌套类ThreadLocalMap中的Entry继承了We ...

  4. java中的WeakReference(弱引用)

    java中的weakReference-弱引用 1.介绍 阅读ThreadLocal源码中,其中嵌套类ThreadLocalMap中的Entry继承了WeakReferenc,为了能搞明白Thread ...

  5. Java中WeakReference,SoftReference,PhantomReference和Strong Reference之间的区别

    很长一段时间以来,WeakReference和SoftReference都已添加到Java API中,但是并不是每个Java程序员都熟悉它. 这意味着在Java中使用WeakReference和Sof ...

  6. Java中WeakHashMap的应用场景

    WeakHashMap是啥: WeakHashMap和HashMap都是通过"拉链法"实现的散列表.它们的源码绝大部分内容都一样,这里就只是对它们不同的部分就是说明. WeakRe ...

  7. java中的softreference_Java中的SoftReference和WeakReference有什么区别?

    问题 Java中的SoftReference和WeakReference有什么区别?它们有什么不同? #1 热门回答(806 赞) 弱引用弱引用,简单地说,是一个不足以强制对象保留在内存中的引用.弱引 ...

  8. Java中的SoftReference和WeakReference有什么区别?

    本文翻译自:What's the difference between SoftReference and WeakReference in Java? java.lang.ref.WeakRefer ...

  9. java中的softreference_Java中的 WeakReference 和 SoftReference

    我们知道Java语言中没有指针,取而代之的是引用reference.Java中的引用又可以分为四种:强引用,弱引用(WeakReference),软引用(SoftReference),虚引用(Phan ...

最新文章

  1. 模板路径,模板变量,过滤器和静态文件的引用
  2. 程序员哪个时间敲代码效率最高?| 每日趣闻
  3. 数据库Sharding的基本思想和切分策略
  4. bzoj2746: [HEOI2012]旅行问题
  5. 外媒:微信小程序顺应“APP中启动APP”的行业潮流
  6. 使用JPA标准@ViewScoped通过分页,过滤和排序进行Primefaces DataTable延迟加载
  7. 【Android】No resource found that matches the given name 'Theme.Sherlock.Light.NoActionBar'
  8. leetcode 1209 python
  9. ssd用HD软件测试准确吗,HDtune到底适不适合用于测试SSD
  10. CrossApp_01
  11. PS基础,灰度色彩模式
  12. java 共享类,Java 技术,IBM 风格: 类共享
  13. Oracle用户管理命令
  14. 网络数据采集技术snmp/netflow/sflow/network telemetry简介
  15. Vue中使用Lodash
  16. echarts柱状图加上渐变色报错问题
  17. 救世之树服务端开服架设服务器搭建教程
  18. Django+sqlite开发简易记账本
  19. 用新浪SAE免费搭建自己的应用
  20. 图像处理--医疗图片的处理

热门文章

  1. idea远程连接hive
  2. 演讲技巧_学习如何进行技术演讲的7个技巧
  3. c语言中inline函数的作用
  4. RESTEasy详解
  5. LIRe:Lucene图像检索 - 可扩展Java CBIR库
  6. 国家信息安全水平考试(NISP一级)考试题库4
  7. linux下遇到bind: Address already in use解决办法
  8. linux平台 加载动态库dlsym返回null
  9. 英文网站的优化设计应该考虑哪些
  10. MySQL的事物级别以及MySQL的锁机制