java中的weakReference-弱引用

1.介绍

阅读ThreadLocal源码中,其中嵌套类ThreadLocalMap中的Entry继承了WeakReferenc,为了能搞明白ThreadLocal,需要对类WeakReference进一步认识。WeakReference如字面意思,弱引用, 当一个对象仅仅被weak reference(弱引用)指向, 而没有任何其他strong reference(强引用)指向的时候, 如果这时GC运行, 那么这个对象就会被回收,不论当前的内存空间是否足够,这个对象都会被回收。

2.类WeakReference源码

public class WeakReference<T> extends Reference<T> {/*** Creates a new weak reference that refers to the given object.  The new* reference is not registered with any queue.** @param referent object the new weak reference will refer to*/public WeakReference(T referent) {super(referent);}/*** Creates a new weak reference that refers to the given object and is* registered with the given queue.** @param referent object the new weak reference will refer to* @param q the queue with which the reference is to be registered,*          or <tt>null</tt> if registration is not required*/public WeakReference(T referent, ReferenceQueue<? super T> q) {super(referent, q);}}
  • WeakReference(T referent):referent就是被弱引用的对象。

  • WeakReference(T referent, ReferenceQueue<? super T> q):referent就是被弱引用的对象,ReferenceQueue队列,当对象referent被系统GC回收时,对象本身(继承WeakReference的对象或WeakReference对象)自动加入ReferenceQueue队列当中。

  • 注意:弱引用对象是WeakReference(referentObject) 中的 referentObject 对象,并不是继承WeakReference的子类

3.例子

3.1 WeakReference 示例1

java类:Computer

/*** @author*/
public class Computer {private String name;public Computer(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}/*** 覆盖finalize,在对象被GC回收的时候会自动执行。* @throws Throwable*/@Overrideprotected void finalize() throws Throwable {super.finalize();System.out.println("Computer GC:  " + name + " finalize!");}@Overridepublic String toString() {return "Computer{" +"name='" + name + '\'' +'}';}
}

java类:Product

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;/*** 产品* 注意:弱引用对象是传入泛型T,不是类Product* @author*/
public class Product<T> extends WeakReference {public Product(T referent) {super(referent);}public Product(Object referent, ReferenceQueue q) {super(referent, q);}
}

Main.test1()方法

public class Main {public static void main(String[] args) {test1();}public static void test1() {Product product = new Product(new Computer("dell"));System.out.println(product);System.out.println(product.get());System.out.println("gc之前");// 执行gc,内存回收System.gc();// 睡眠1s,等待系统回收内存try {System.out.println("等待1s...");Thread.sleep(1000L);} catch (Exception e) {e.printStackTrace();}System.out.println("gc之后");System.out.println(product);System.out.println(product.get());}
}

执行输出

# product引用对象
test1.Product@1b6d3586
# product.computer弱引用对象输出
Computer{name='dell'}
gc之前
等待1s...
# computer对象自动回收方法回调
Computer GC:  dell finalize!
gc之后
# product引用对象
test1.Product@1b6d3586
# product.computer弱引用对象输出
null

结论:

  1. 弱引用对象是WeakReference(referentObject) 中的 referentObject 对象。
  2. JVM,自动GC或者是手动GC, 不论当前的内存空间是否足够,弱引用对象都会被回收。
  3. 其他,弱引用对象在使用时要严谨,可能会造成内存泄漏,造成内存浪费;ThreadLocal会造成内存泄漏。

3.2 WeakReference 示例2

ReferenceQueue的使用

public class Main {public static void main(String[] args) {test2();}public static void test2() {ReferenceQueue<Computer> referenceQueue = new ReferenceQueue<>();WeakReference<Computer> weakReference1 = new WeakReference<Computer>(new Computer("Dell"), referenceQueue);WeakReference<Computer> weakReference2 = new WeakReference<Computer>(new Computer("Apple"), referenceQueue);System.out.println("=====gc调用前=====");Reference<? extends Computer> reference1 = null;while ((reference1 = referenceQueue.poll()) != null) {System.out.println(reference1);}System.out.println(weakReference1);System.out.println(weakReference2);System.out.println(weakReference1.get());System.out.println(weakReference2.get());System.out.println("=====调用gc=====");System.gc();try {Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("=====gc调用后=====");//下面两个输出为null,表示对象被回收了System.out.println(weakReference1.get());System.out.println(weakReference2.get());//输出结果,并且就是上面的appleWeakReference、appleWeakReference2,再次证明对象被回收了Reference<? extends Computer> reference2 = null;while ((reference2 = referenceQueue.poll()) != null) {//如果使用继承的方式就可以包含其他信息了System.out.println("referenceQueue:" + reference2);}}

输出

=====gc调用前=====
java.lang.ref.WeakReference@39a054a5
java.lang.ref.WeakReference@71bc1ae4
Computer{name='Dell'}
Computer{name='Apple'}
=====调用gc=====
Computer GC:  Apple finalize!
Computer GC:  Dell finalize!
=====gc调用后=====
null
null
referenceQueue:java.lang.ref.WeakReference@39a054a5
referenceQueue:java.lang.ref.WeakReference@71bc1ae4

结论:

  1. ReferenceQueue队列,当对象referent被系统GC回收时,继承WeakReference的对象或WeakReference对象自动加入ReferenceQueue队列当中。

java中的WeakReference(弱引用)相关推荐

  1. 说说WeakReference弱引用

    WeakReference弱引用概述 http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文 Java里一个对象obj被创建 ...

  2. WeakReference弱引用

    WeakReference弱引用 什么是弱引用 顾名思义,弱引用,当一个对象仅仅被weak reference(弱引用)指向并且没有其它对象strong reference(强引用)指向,这时GC运行 ...

  3. Java 中的四种引用

    垃圾收集器与内存分配策略参考目录: 1.判断Java 对象实例是否死亡 2. Java 中的四种引用 3.垃圾收集算法 4. Java9中的GC 调优 5.内存分配与回收策略 在进行垃圾回收之前,虚拟 ...

  4. java中是值传递引用传递_Java是按值传递而不是按引用传递

    java中是值传递引用传递 One of the biggest confusion in Java programming language is whether java is Pass by V ...

  5. Java中基本数据类型和引用数据类型的区别

    Java中基本数据类型和引用数据类型的区别 一.数据类型 1.基本数据类型 2.引用数据类型 二.基本数据类型和引用数据类型的区别 1.储存位置 基本变量类型 引用变量类型 2.参数传递方式 基本变量 ...

  6. Java中基本数据类型和引用数据类型的存放位置

    Java中基本数据类型和引用数据类型的存放位置 1.基本数据类型存放在哪? 基本类型的变量存在栈里或者堆里不是由"大小可知,生存期可知"就能确定了.关键是上下文. 比如: void ...

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

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

  8. Java 中的四种引用及垃圾回收策略

    Java 中有四种引用:强引用.软引用.弱引用.虚引用: 其主要区别在于垃圾回收时是否进行回收: 1.强引用 使用最普遍的引用.如果一个对象具有强引用,那就 类似于必不可少的生活用品,垃圾回收器绝不会 ...

  9. Java中的四种引用方式的区别

    强引用.软引用.弱引用.虚引用的概念 ps:我更新了.....我真的更新了.....因为博客园不支持MarkDown,而且取了一个很low的用户名,所以不用了..... 强引用(StrongRefer ...

最新文章

  1. php自动生成新闻页,自动发布新闻页面的php代码
  2. python 计时_Python计时相关操作详解【time,datetime】
  3. php会员权限分析,PHP会员权限控制-很详细(转)
  4. 秋招面试我去了拼多多,直接被问JVMGC底层原理和算法,我吊打面试官
  5. 自然语言处理领域基本概念笔记
  6. kotlin 查找id_Kotlin程序查找给定范围内的素数
  7. 华为3COM交换机PVLAN配置使用说明
  8. 如何做好软件测试管理工作,如何才能做好软件测试工作
  9. MySql(四):备份与恢复
  10. 从0-1背包问题到动态规划
  11. Android 实现 相机、相册功能 + 图片存取数据库操作
  12. cydia无法安装卸载插件_【初识太极】CAD卸载不干净无法重新安装怎么办?
  13. Dev ChartControl 显示设置百分比
  14. Lu窗口库LuWin
  15. Windows消息前缀
  16. 软件功能性测试方法和流程
  17. LED点阵屏动画展示
  18. Java-热插拔技术
  19. 二维曲线 去噪点 c++_二维介孔聚吡咯-氧化石墨烯异质结用于制备无枝晶的锂金属负极...
  20. Gitter:高颜值GitHub小程序客户端诞生记

热门文章

  1. 职场寒冬 请不要让码农只活在青春里~
  2. 房贷计算器2023-免费的贷款按揭计算器- Tech Support
  3. 魔兽世界:盗贼20级制毒任务全攻略
  4. 基于预留子载波的PAPR抑制算法matlab仿真
  5. 谷歌搜索广告可以加产品图片吗?
  6. python drf_python drf各类组件的用法和作用
  7. 我找不到我的电子邮件从 Outlook 数据文件 (.pst) 导入后,收发功能正常
  8. 多普达P800硬启动的方法
  9. python runtime错误_python出现RuntimeError错误
  10. Linux screen简单用法