一个对象被回收,必须满足两个条件: 没有任何引用指向它和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的更多相关文章

  1. Java的Reference感觉很象C++的指针,但是区别是本质的

    Java的Reference感觉很象C++的指针,但是区别是本质的 他们相同之处在于都是含有一个地址,但是在Java中你无法对这个地址进行任何数学运算,并且这个地址你不知道,是Java Runtime ...

  2. Java Interview Reference Guide--reference

    Part 1 http://techmytalk.com/2014/01/24/java-interview-reference-guide-part-1/ Posted on January 24, ...

  3. Java基本功—Reference

    这是一篇一年多之前便已写就的文章,那时,因为很多Java程序员只求追随新生的事物,却连基本的概念都没有,很多讨论中,很明显是基本功不过硬,于是萌生写一个系列文章,讨论Java的基本功,下面便是在这个想 ...

  4. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  5. thinking in java 之Reference类的使用

    Reference是java中的特殊引用类.描述的是特殊作用(主要是关于垃圾回收对象)的引用. 它有3个子类: 1.SoftReference; 2.WeakReference 3.PhantomRe ...

  6. 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 ...

  7. java基础---->Reference的使用(一)

    这里记录一些java中关于引用的知识. java中的引用 一.java中关于引用的测试 public class ReferenceTest { public static void main(Str ...

  8. Jerry的ABAP, Java和JavaScript乱炖

    写这个系列的初衷是SAP Chengdu office有越来越多的应届毕业生加入,这些新同事通过在大学的专业学习,具备了Java和JavaScript背景,但是进入SAP之后大家觉得ABAP没有Jav ...

  9. Java.WeakReference-SoftReference-PhantomReference

    Weak Reference, Soft Reference, Phantom Reference 1. Introduction "Weak reference objects, whic ...

随机推荐

  1. STL容器之优先队列

    STL容器之优先队列 优先级队列,以前刷题的时候用的比较熟,现在竟然我只能记得它的关键字是priority_queue(太伤了).在一些定义了权重的地方这个数据结构是很有用的. 先回顾队列的定义:队列 ...

  2. POJ 1273 Drainage Ditches【最大流模版】

    题意:现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条有向水渠,给出这n条水渠所连接的点和所能流过的最大流量,求从源点到汇点能流过的最大流量 Dinic #include<iost ...

  3. Java基础知识➣泛型整理(四)

    概述 泛型的本质是参数化类型,使用同一套代码来满足不同数据类型的业务需要,提高代码的执行效率,使代码简单明了. 泛型方法 该方法在调用时可以接收不同类型的参数.根据传递给泛型方法的参数类型,编译器适当 ...

  4. 如何使用maven进行avro序列化

    maven导入avro: <dependency> <groupId>org.apache.avro</groupId> <artifactId>avr ...

  5. jquery 计算两个日期相差的天数

    <!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title&g ...

  6. Java 异常处理的重要认识

    异常类的继承结构 Exception : 一般标识的是程序中出现的问题,可以直接使用try---catch处理. Error : 一般值得是JVM错误,程序中无法处理. 检测异常类需要在throws后 ...

  7. Best Reward 拓展kmp

    Problem Description After an uphill battle, General Li won a great victory. Now the head of state de ...

  8. day 68 django 之api操作 | jQueryset集合与对象

    我们的orm里面分为: jQueryset集合, 还有对象, 我们的jqueryset集合里面可以有多个对象,这句话的意思就是我们的对象是最小的单位,不可以再拆分了,我们的jQueryset集合就相当 ...

  9. 【JavaScript】对象

    No1: typeof操作符获取对象的类型 null的类型是object,Array的类型也是object,如果我们用typeof将无法区分出null.Array和通常意义上的object——{}. ...

  10. componentWillReceiveProps详解(this.props)状态改变检测机制

    参考资料:http://blog.csdn.net/ElinaVampire/article/details/51813677 大家先看一张关于组件挂载的经典的图片: 下面一一说一下这几个生命周期的意 ...