java中的WeakReference(弱引用)
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
结论:
- 弱引用对象是WeakReference(referentObject) 中的 referentObject 对象。
- JVM,自动GC或者是手动GC, 不论当前的内存空间是否足够,弱引用对象都会被回收。
- 其他,弱引用对象在使用时要严谨,可能会造成内存泄漏,造成内存浪费;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
结论:
- ReferenceQueue队列,当对象referent被系统GC回收时,继承WeakReference的对象或WeakReference对象自动加入ReferenceQueue队列当中。
java中的WeakReference(弱引用)相关推荐
- 说说WeakReference弱引用
WeakReference弱引用概述 http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文 Java里一个对象obj被创建 ...
- WeakReference弱引用
WeakReference弱引用 什么是弱引用 顾名思义,弱引用,当一个对象仅仅被weak reference(弱引用)指向并且没有其它对象strong reference(强引用)指向,这时GC运行 ...
- Java 中的四种引用
垃圾收集器与内存分配策略参考目录: 1.判断Java 对象实例是否死亡 2. Java 中的四种引用 3.垃圾收集算法 4. Java9中的GC 调优 5.内存分配与回收策略 在进行垃圾回收之前,虚拟 ...
- java中是值传递引用传递_Java是按值传递而不是按引用传递
java中是值传递引用传递 One of the biggest confusion in Java programming language is whether java is Pass by V ...
- Java中基本数据类型和引用数据类型的区别
Java中基本数据类型和引用数据类型的区别 一.数据类型 1.基本数据类型 2.引用数据类型 二.基本数据类型和引用数据类型的区别 1.储存位置 基本变量类型 引用变量类型 2.参数传递方式 基本变量 ...
- Java中基本数据类型和引用数据类型的存放位置
Java中基本数据类型和引用数据类型的存放位置 1.基本数据类型存放在哪? 基本类型的变量存在栈里或者堆里不是由"大小可知,生存期可知"就能确定了.关键是上下文. 比如: void ...
- 关于Java中的WeakReference类的笔记(弱引用)
前言 今天在看ThreadLocal源码的时候,其中内部类ThreadLocalMap中的Entry继承了WeakReferenc,为了能搞清楚ThreadLocal,只能先了解下了WeakRefer ...
- Java 中的四种引用及垃圾回收策略
Java 中有四种引用:强引用.软引用.弱引用.虚引用: 其主要区别在于垃圾回收时是否进行回收: 1.强引用 使用最普遍的引用.如果一个对象具有强引用,那就 类似于必不可少的生活用品,垃圾回收器绝不会 ...
- Java中的四种引用方式的区别
强引用.软引用.弱引用.虚引用的概念 ps:我更新了.....我真的更新了.....因为博客园不支持MarkDown,而且取了一个很low的用户名,所以不用了..... 强引用(StrongRefer ...
最新文章
- php自动生成新闻页,自动发布新闻页面的php代码
- python 计时_Python计时相关操作详解【time,datetime】
- php会员权限分析,PHP会员权限控制-很详细(转)
- 秋招面试我去了拼多多,直接被问JVMGC底层原理和算法,我吊打面试官
- 自然语言处理领域基本概念笔记
- kotlin 查找id_Kotlin程序查找给定范围内的素数
- 华为3COM交换机PVLAN配置使用说明
- 如何做好软件测试管理工作,如何才能做好软件测试工作
- MySql(四):备份与恢复
- 从0-1背包问题到动态规划
- Android 实现 相机、相册功能 + 图片存取数据库操作
- cydia无法安装卸载插件_【初识太极】CAD卸载不干净无法重新安装怎么办?
- Dev ChartControl 显示设置百分比
- Lu窗口库LuWin
- Windows消息前缀
- 软件功能性测试方法和流程
- LED点阵屏动画展示
- Java-热插拔技术
- 二维曲线 去噪点 c++_二维介孔聚吡咯-氧化石墨烯异质结用于制备无枝晶的锂金属负极...
- Gitter:高颜值GitHub小程序客户端诞生记