转:https://blog.csdn.net/zmx729618/article/details/54093532

看到篇帖子, 国外一个技术面试官在面试senior java developer的时候, 问到一个weak reference相关的问题. 他没有期望有人能够完整解释清楚weak reference是什么, 怎么用, 只是期望有人能够提到这个concept和java的GC相关. 很可惜的是, 20多个拥有5年以上java开发经验的面试者中, 只有两人知道weak reference的存在, 而其中只有一人实际用到过他. 无疑, 在interviewer眼中, 对于weak reference的理解和应用在面试中给了这一个interviewee相当多的加分.  所以, 将我对于这个技术的理解和使用总结在这篇博客里, 希望读者和自己通过读和写这篇帖子, 能够在以后的工作和面试中获得加分.

在Java里, 当一个对象o被创建时, 它被放在Heap里. 当GC运行的时候, 如果发现没有任何引用指向o, o就会被回收以腾出内存空间. 或者换句话说, 一个对象被回收, 必须满足两个条件: 1)没有任何引用指向它 2)GC被运行.

在现实情况写代码的时候, 我们往往通过把所有指向某个对象的referece置空来保证这个对象在下次GC运行的时候被回收 (可以用java -verbose:gc来观察gc的行为)

Object c = new Car();
c=null;

但是, 手动置空对象对于程序员来说, 是一件繁琐且违背自动回收的理念的.  对于简单的情况, 手动置空是不需要程序员来做的, 因为在java中, 对于简单对象, 当调用它的方法执行完毕后, 指向它的引用会被从stack中popup, 所以他就能在下一次GC执行时被回收了.

但是, 也有特殊例外. 当使用cache的时候, 由于cache的对象正是程序运行需要的, 那么只要程序正在运行, cache中的引用就不会被GC给(或者说, cache中的reference拥有了和主程序一样的life cycle). 那么随着cache中的reference越来越多, GC无法回收的object也越来越多, 无法被自动回收. 当这些object需要被回收时, 回收这些object的任务只有交给程序编写者了. 然而这却违背了GC的本质(自动回收可以回收的objects).

所以, java中引入了weak reference. 相对于前面举例中的strong reference:

Object c = new Car(); //只要c还指向car object, car object就不会被回收

当一个对象仅仅被weak reference指向, 而没有任何其他strong reference指向的时候, 如果GC运行, 那么这个对象就会被回收. weak reference的语法是:

WeakReference<Car> weakCar = new WeakReference(Car)(car);

当要获得weak reference引用的object时, 首先需要判断它是否已经被回收:

weakCar.get();

如果此方法为空, 那么说明weakCar指向的对象已经被回收了.

下面来看一个例子:

 
  1. package weakreference;

  2. /**

  3. * @author wison

  4. */

  5. public class Car {

  6. private double price;

  7. private String colour;

  8. public Car(double price, String colour){

  9. this.price = price;

  10. this.colour = colour;

  11. }

  12. public double getPrice() {

  13. return price;

  14. }

  15. public void setPrice(double price) {

  16. this.price = price;

  17. }

  18. public String getColour() {

  19. return colour;

  20. }

  21. public void setColour(String colour) {

  22. this.colour = colour;

  23. }

  24. public String toString(){

  25. return colour +"car costs $"+price;

  26. }

  27. }

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." 说明, weak reference指向的对象的被回收了.

值得注意的一点 , 即使有 car 引用指向对象, 且 car 是一个strong reference, weak reference weakCar指向的对象仍然被回收了. 这是因为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;}}}}

weak reference指向的object就不会被回收了. 因为还有一个strong reference car 指向它.

* WeakReference的一个特点是它何时被回收是不可确定的, 因为这是由GC运行的不确定性所确定的. 所以, 一般用weak reference引用的对象是有价值被cache, 而且很容易被重新被构建, 且很消耗内存的对象.

ReferenceQueue

在weak reference指向的对象被回收后, weak reference本身其实也就没有用了. java提供了一个ReferenceQueue来保存这些所指向的对象已经被回收的reference. 用法是在定义WeakReference的时候将一个ReferenceQueue的对象作为参数传入构造函数.

其他类型的references

-SoftReference

soft reference和weak reference一样, 但被GC回收的时候需要多一个条件: 当系统内存不足时(GC是如何判定系统内存不足? 是否有参数可以配置这个threshold?), soft reference指向的object才会被回收. 正因为有这个特性, soft reference比weak reference更加适合做cache objects的reference. 因为它可以尽可能的retain cached objects, 减少重建他们所需的时间和消耗.

Java弱引用(WeakReference)的理解与使用相关推荐

  1. Java弱引用(WeakReference)

    最近在看ThreadLocal,看到WeakReference,学习一下 ExecutorService executorService = Executors.newCachedThreadPool ...

  2. java弱引用怎么手动释放,十分钟理解Java中的弱引用,十分钟java引用

    十分钟理解Java中的弱引用,十分钟java引用 本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,帮助大家理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限 ...

  3. Android 弱引用 (WeakReference)的使用

    1 弱引用 (WeakReference) 弱引用对象,这些对象不会阻止对其引用对象进行终结,终结和回收.弱引用最常用于实现规范化映射.假设垃圾收集器在某个时间点确定对象是弱可到达的.到那时,它将自动 ...

  4. java弱引用怎么手动释放,Java 如何有效地避免OOM:善于利用软引用和弱引用

    前言 想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引用来有效地解决程序中出现的OOM问题. 一.了解 ...

  5. java弱引用弱点_终于有人把Java强、软、弱、虚四种引用知识点整理出来了

    强引用就是指在程序代码之中普遍存在的,指创建一个对象并把这个对象赋给一个引用变量,并没有像其它三种引用一样有一个就具体的类来描述.对于强引用对象,即使内存不足,JVM宁愿抛出OutOfMemoryEr ...

  6. java引用 弱引用_了解Java弱引用

    java引用 弱引用 我最近没来得及关注这个博客,最重要的是,我没有为与技术界的所有人保持联系而致歉. 最近,我偶然发现了自Java 1.2起可用的java.lang.ref软件包,但具有讽刺意味的是 ...

  7. java弱引用在安卓中有效吗_Android 软引用和弱引用详解及实例代码

    Android 软引用 和 弱引用 1.  SoftReference:软引用-->当虚拟机内存不足时,将会回收它指向的对象:需要获取对象时,可以调用get方法. 2.  WeakReferen ...

  8. 弱引用WeakReference和软引用SoftReference

    在Java1.2中我们可以发现一个java.lang.ref包,在这个包中我们可以发现有关引用的知识,比如WeakReference弱引用和SoftReference强引用. 弱引用(WeakRefe ...

  9. 弱引用WeakReference作用与使用场景

    文章目录 1. Demo 2. 使用场景 在分析threadLocal源码时,发现有使用弱引用WeakReference,在之前总结GC的时候,也曾简单介绍java引用类型(<jvm GC算法类 ...

最新文章

  1. lua 收不到服务器发来消息,lua 学习之错误处理
  2. Ghost 系统的过程
  3. nlp算法文本向量化_NLP中的标记化算法概述
  4. 空间谱专题11:子阵平滑与秩亏缺
  5. js之函数设置默认值传参
  6. 森林怎么训练野人_138年前抓的“野人女孩”,最终命运如何?死前心愿让人心酸...
  7. 【图像处理】MATLAB:彩色图像处理
  8. dao层如何调用对象_如何实现DBCP数据库连接池工具类&mvc分层开发web流程操作?...
  9. html 表单在当前窗口打开,js使用post 方式打开新窗口
  10. DVB 数字电视基础知识
  11. DjVu、PDF中的隐藏文本
  12. excel 的lookup和sumifs函数使用
  13. 蓝桥ROS机器人系统更新和功能包安装记录
  14. vue3采用xlsx库实现上传excel文件,前端解析展示数据(日期转换问题解决)
  15. java怎么对数组中数据进行降序排序?
  16. python每日学4:vscode的安装与基础使用
  17. 感恩节和感恩节的由来!
  18. 赛维时代IPO过会:第一季净利降71% 出口跨境电商热度降温
  19. “黄金州”不再宜居?这些城市被列入美国空气最差排行榜,近三分之一美国人受影响 | 美通社头条...
  20. SimSum.ttf下载

热门文章

  1. 第三十五期:当我们在讨论CQRS时,我们在讨论些神马?
  2. 玩转oracle 11g(23):区分大小写和字符集不同
  3. emqx使用webhook数据持久化到mysql
  4. Qt 两个Ui 界面传值
  5. itchat 保存好友信息以及生成好友头像图片墙
  6. c++ class struct同名_相对于C语言,C++对struct做了非常多的扩充,功能更全面了
  7. 80211 发送速率选择算法分析
  8. 不同操作系统打开文件浏览器(资源管理器)的方式
  9. Javascript与C#中使用正则表达式
  10. 程序员的生存发展和出路