Java的四种引用类型之弱引用
先说结论:
首先,Java中有四种引用类型:强引用、软引用、弱引用、虚引用。-- 在 Java 1.2 中添加的,见 package java.lang.ref; 。
其次,这几个概念是与垃圾回收有关的。
然后,如果你不知道这几个概念,那你用的肯定都是强引用。例如 String str = new String(); 这个 str 到 new String() 的引用类型就是强引用。
那么弱引用是什么?
弱引用,就是引用与对象之间的联系很弱,弱到垃圾回收器会无视这个引用,直接回收对象。
软引用与弱引用类似,但只在内存不足时才会被回收。
虚引用最差,甚至不能通过 get() 获取到对象。
为什么需要弱引用?
先看一段代码:
package cn.larry.weakref.pojo; public final class Product {
private String name; public Product() {
super();
} public Product(String name) {
super();
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Product [name=" + name + "]";
} }
package cn.larry.weakref.test; import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap; import org.junit.Test; import cn.larry.weakref.pojo.Product; public class WrTest {
private Product product = new Product("iPhone"); @Test
public void strongRef() {
Map<Product, Integer> map = new HashMap<>();
map.put(product, 111); product = null;// 关键
map.keySet().forEach(System.out::println);// 对象仍然存在!
}
}
在上面的代码中,虽然在第21行已经将 product引用置空(null),但是第22行的代码仍然可以访问到该引用最初指向的对象!
这时,如果map中有多个Key,Product类又不可修改(不能添加识别字段),那你怎么确定并删除这个Key,能否自动移除该Key?弱引用就可以满足这样的要求。
一个经典的场景就是缓存,特别是缓存图片(加载到内存中),此时缓存肯定会包含一个指向内存中图片缓存的引用。问题在于,如果使用强引用,你必须决定何时不再需要该缓存并手动移除它。
怎么使用弱引用?
代码如下(与上面的测试代码在同一个 WrTest 类中):
@Test
public void weakRef_1() { ReferenceQueue<Product> rq = new ReferenceQueue<>();
// WeakReference<Product> wr=new WeakReference<Product>(product);
WeakReference<Product> wr = new WeakReference<Product>(product, rq);// 引用队列
System.out.println("wr是否已被添加至引用队列:" + wr.isEnqueued()); Map<WeakReference<Product>, Integer> map = new HashMap<>();
map.put(wr, 111); product = null;// 关键
// System.gc();// 关键 map.keySet().forEach(e -> System.out.println(e.get()));// 不gc()的话,还能访问对象,否则null。
System.out.println("wr是否已被添加至引用队列:" + wr.isEnqueued());
}
上面第4行构造了一个引用队列。
第5或6行构造了一个弱引用,区别在于是否指定引用队列。
如果指定了弱引用的引用队列,垃圾回收器会在回收对象之后将该弱引用添加至引用队列中 -- 可以在回收之后通过弱引用的 isEnqueued() 方法来判断。
需要注意:①必须将原强引用置空(第12行),且不能有其他强引用指向该对象;②必须主动调用垃圾回收器(第13行)。然后就能看到弱引用指向的对象已经不存在了(第15行) -- 弱引用本身还存在,所以map不为空。
但是,这时已经可以手动删除这个Key了。
更便捷的方法:
JDK提供了 WeakHashMap 可以更加方便的完成上面的工作,代码如下:
@Test
public void weakRef_2() {
WeakHashMap<Product, Integer> map = new WeakHashMap<>();
map.put(product, 111); product = null;// 关键
// System.gc();//关键 map.keySet().forEach(System.out::println);// 不gc()的话,还能访问对象,否则null。 }
这种情况下,map.size()是0,即该Key自动被移除!!!
补充说明:
1、虽然可以主动调用垃圾回收器,但垃圾回收器并不总是会执行的。
2、Product类参考了 理解Java中的弱引用(Weak Reference) 中的pojo类。
参考
理解Java中的弱引用(Weak Reference) 译文:理解Java中的弱引用Java的四种引用类型之弱引用的更多相关文章
- java中四种引用类型(对象的强、软、弱和虚引用)
对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2 ...
- java中四种引用类型
java中四种引用类型 今天看代码,里面有一个类java.lang.ref.SoftReference把小弟弄神了,试想一下,接触java已经有3年了哇,连lang包下面的类都不了解,怎么混.后来在 ...
- 你知道Java的四种引用类型吗
关于java四种引用类型,我也是刚了解,特此记下! 在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用.在这四个引用类型中,只有强引用FinalReference类是包内可见,其他三种引 ...
- java的四种引用类型
java的引用分为四个等级:4种级别由高到低依次为:强引用.软引用.弱引用和虚引用. ⑴强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回 ...
- java中四种引用类型(转)
今天看代码,里面有一个类java.lang.ref.SoftReference把小弟弄神了,试想一下,接触java已经有3年了哇,连lang包下面的类都不了解,怎么混.后来在网上查资料,感觉收获颇多, ...
- Java中的四种引用类型,强引用,软引用,弱引用,虚引用
对于Java中的垃圾回收机制来说,对象是否被回收的标准在于该对象是否被引用.因此,引用也是JVM进行内存管理的一个重要概念. Java中对象的引用一般有以下4种类型: 1强引用 2软引用 3弱引用 ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- java基础之 数据类型 & 值传递 引用传递 & String & 四种引用类型
一.Java数据类型 分为基本数据类型与引用数据类型 基本数据类型: byte:Java中最小的数据类型,在内存中占1个字节(8 bit),取值范围-128~127,默认值0 short:短整型,2个 ...
- Java魔法堂:四种引用类型、ReferenceQueue和WeakHashMap
一.前言 JDK1.2以前只提供一种引用类型——强引用 Object obj = new Object(); .而JDK1.2后我们多另外的三个选择分别是软引用 java.lang.ref.SoftR ...
随机推荐
- Meta Blogging
Meta Blogging 由来 偶然想到说如果哪一天cnblogs挂了,那之前记录的随笔怎么办?可不可以把它们给download下来本地保存一份.正好看到有个库叫requests, 干嘛不试试看呢. ...
- 服务器搭建2 VSFTP搭建FTP服务器
FTP服务器是平时应用最为广泛的服务之一.VSFTP是Very Secure FTP的缩写,意指非常安全的FTP服务.VSFTP功能强大,通过结合本地系统的用户认证模块及其多功能的配置项目,可以快速有 ...
- vs2010静态链接Qt
先按照这个帖子弄好静态库 http://www.cnblogs.com/rollenholt/articles/2518642.html 注意原文中config那一步最后一个"-" ...
- u-boot mkconfig文件分析
#!/bin/sh -e #遇到非0返回 就退出脚本 # Script to create header files and links to configure # U-Boot for a spe ...
- 带包的java类在cmd环境下的执行办法
带包的java类在cmd环境下的执行办法:工程目录为D:\Program Files\eclipse\workspace\ReadFileByLinesUniq上面目录下有两个文件夹bin和src源文 ...
- [已修正]安装struts找不到tld文件
今天安装的struts1.3,但是缺少tld文件,所以无法使用taglib,找了半天 假设你的struts版本为1.3.10 解压后的目录为F:\struts-1.3.10-all\struts-1. ...
- 【AUC】二分类模型的评价指标ROC Curve
AUC是指:从一堆样本中随机抽一个,抽到正样本的概率比抽到负样本的概率大的可能性! AUC是一个模型评价指标,只能用于二分类模型的评价,对于二分类模型,还有很多其他评价指标,比如logloss,acc ...
- mysql status
要查看MySQL运行状态,要优化MySQL运行效率都少不了要运行show status查看各种状态,下面是参考官方文档及网上资料整理出来的中文详细解释: 状态名 作用域 详细解释 Aborted_cl ...
- HTML5的video虽然可用controls来展示控件
HTML5的video虽然可用controls来展示控件,并进行控制播放暂停等,但是不同的浏览器显示的效果可能不一样,所以很多时候我们需要使用Dom来进行自定义的一些操作和控制.下面是一个小例子. 当 ...
- 在N个元素的数组中获取K个元素的所有组合问题
可以写循环,也可以用模块. 百度许久找到一个博客 http://blog.sina.com.cn/s/blog_4a0824490101f1kc.html 详细介绍了Algorithm::Combin ...