Java weak reference
一个对象被回收,必须满足两个条件: 没有任何引用指向它和GC在运行。把所有指向某个对象的引用置空来保证这个对象在下次GC运行时被回收。
Object c = new Car();
c = null;
手动置空对象是繁琐且违背自动回收理念的。对于简单对象,当使用它的方法执行完毕后,指向它的引用会出栈,所以在下一次GC执行时会回收它。但是缓存中的引用的生命周期与主程序一致。回收缓存中的对象需要程序员去做,这违背了GC的本质(自动回收可以回收的对象)。
相对于前面的强引用(strong reference),Java中引入了弱引用(weak reference)。如果一个对象仅被弱引用指向,那么GC运行时会回收这个对象。弱引用语法:
WeakReference<Car> weakCar = new WeakReference(Car)(car);
当要获取弱引用指向的对象时,需要判断它是否已经被回收:
weakCar.get();
如果此方法返回值为空,则说明weakCar指向的对象已经被回收了。
实例:
package weakreference;
/**
* @author wison
*/
public class Car {
private double price;
private String colour; public Car(double price, String colour){
this.price = price;
this.colour = colour;
} public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
} public String toString(){
return colour +"car costs $"+price;
} }
package weakreference; import java.lang.ref.WeakReference; /**
* @author wison
*/
public class TestWeakReference { public static void main(String[] args) { Car car = new Car(22000,"silver");
WeakReference<Car> weakCar = new WeakReference<Car>(car); int i=0; while(true){
if(weakCar.get()!=null){
i++;
System.out.println("Object is alive for "+i+" loops - "+weakCar);
}else{
System.out.println("Object has been collected.");
break;
}
}
} }
程序运行一段时间后打印出“Object has been collected.",说明弱引用指向的对象被回收了。Java编译器进入while循环后发现强引用car已经没有被使用了,所以进行了优化。
修改TestWeakReference.java:
package weakreference; import java.lang.ref.WeakReference; /**
* @author wison
*/
public class TestWeakReference { public static void main(String[] args) { Car car = new Car(22000,"silver");
WeakReference<Car> weakCar = new WeakReference<Car>(car); int i=0; while(true){
System.out.println("here is the strong reference 'car' "+car);
if(weakCar.get()!=null){
i++;
System.out.println("Object is alive for "+i+" loops - "+weakCar);
}else{
System.out.println("Object has been collected.");
break;
}
}
} }
弱引用指向的对象不会被回收,因为while循环体里面使用了强引用指向的对象。GC运行的不确定性决定了弱引用指向的对象回收时机的不确定性。所以用弱引用指向的对象是有价值被缓存的,且是很消耗内存的对象。
ReferenceQueue
在弱引用指向的对象被回收后,Java提供了一个ReferenceQueue来保存指向的对象已经被回收的引用,用法是在定义WeakReference时将一个ReferenceQueue的对象作为参数传入构造函数。
其他类型的引用
soft reference
soft reference和weak reference一样,但被GC回收时多1个条件:当系统内存不足时,soft reference指向的对象才会被回收。因此,soft reference比weak reference更适合成为缓存对象的引用,尽可能地维持缓存对象,减少创建它们所需的空间和时间。
phantom reference、WeakHashMap和WeakCache
to be continued
参考资料
不只是给面试加分 -- Java WeakReference的理解与使用
Java weak reference的更多相关文章
- Java的Reference感觉很象C++的指针,但是区别是本质的
Java的Reference感觉很象C++的指针,但是区别是本质的 他们相同之处在于都是含有一个地址,但是在Java中你无法对这个地址进行任何数学运算,并且这个地址你不知道,是Java Runtime ...
- Java Interview Reference Guide--reference
Part 1 http://techmytalk.com/2014/01/24/java-interview-reference-guide-part-1/ Posted on January 24, ...
- Java基本功—Reference
这是一篇一年多之前便已写就的文章,那时,因为很多Java程序员只求追随新生的事物,却连基本的概念都没有,很多讨论中,很明显是基本功不过硬,于是萌生写一个系列文章,讨论Java的基本功,下面便是在这个想 ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- thinking in java 之Reference类的使用
Reference是java中的特殊引用类.描述的是特殊作用(主要是关于垃圾回收对象)的引用. 它有3个子类: 1.SoftReference; 2.WeakReference 3.PhantomRe ...
- How to Check if an Array Contains a Value in Java Efficiently?---reference
How to check if an array (unsorted) contains a certain value? This is a very useful and frequently u ...
- java基础---->Reference的使用(一)
这里记录一些java中关于引用的知识. java中的引用 一.java中关于引用的测试 public class ReferenceTest { public static void main(Str ...
- Jerry的ABAP, Java和JavaScript乱炖
写这个系列的初衷是SAP Chengdu office有越来越多的应届毕业生加入,这些新同事通过在大学的专业学习,具备了Java和JavaScript背景,但是进入SAP之后大家觉得ABAP没有Jav ...
- Java.WeakReference-SoftReference-PhantomReference
Weak Reference, Soft Reference, Phantom Reference 1. Introduction "Weak reference objects, whic ...
随机推荐
- Mac Mojave(10.14.1)执行Matlab的mex报错
先装了matlab2018b,发现很频繁的crash,同时考虑到要跑的代码在>=2017a时就计算错误,于是转战matlab2016b matlab2016b安装后,执行mex -setup报错 ...
- Tomcat8 启动慢 Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [53,161] milliseconds
修改$JAVA_PATH/jre/lib/security/java.security文件 将 securerandom.source=file:/dev/random 修改为 securerando ...
- CDOJ 1965 连通域统计【DFS】
求连通域个数,简单题 #include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; typedef l ...
- fatal error c1001 编译器中发生内部错误 OpenMesh6.3
Internal Compiler Error VS 2015 Update1 VS2015 Update1 编译OpenMesh的额代码时发生错误 fatal error c1001 编译器中发生内 ...
- alpha冲刺2/10
目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:拿快递也不能耽搁了软工 团队部分 后敬甲(组长) 过去两天完成了哪些任务 文字描述 github代码管理规范 商家端订单 ...
- [转]搭建Hadoop伪分布式环境
https://my.oschina.net/MyHeaven1987/blog/1821509 http://hadoop.apache.org/docs/current/hadoop-projec ...
- Ubuntu14.04创建无线WiFi,android可以连接上网
前提条件: ubuntu14.04 unity,已经通过有线连接到internet 一般环境下创建的wifi热点android设备是无法识别的,网上说通过ap-hotspot方式创建出来的热点手机可以 ...
- 未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序。
问题描述:运行访问oracle数据库的.net程序时,弹出错误"未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序". 系统环境:windows server 2 ...
- Python_shutil模块
import shutil 高级的文件,文件夹,压缩包的处理模块,也主要用于文件的拷贝 shutil.copyfileobj(fsrc,fdst[,length]): 将文件的内容拷贝到另一个文件(可 ...
- You have new mail in /var/spool/mail/root消除提示的方法
有时在进入系统的时候经常提示You have new mail in /var/spool/mail/root 你觉得烦人---解决方法: 修改系统配置文件/etc/profile,告诉系统不要去检查 ...