Java中的引用

  Java“引用”的概念源于C++,原本的定义相当有限:一个引用(Reference)代表的内存通常用于指向另一块内存区域的起始地址。通过引用类型保存的起始地址,可以找到这个引用所指向的对象实例和在方法区中的对象类型数据。

  区别于传统的c/c++语言,Java的对象的销毁完全由垃圾回收器管理,核心问题就是何时应该回收对象?

  Java的策略是:回收那些再也不会被任何引用指向的对象,我们将实例化对象的是否被引用的特性称之为可达性

  其实,这种策略并不涵盖所有的使用情景。试想,我们希望创建一些缓存对象用于存储临时的中间计算结果,当内存充裕时将它们会保留在内存中;当内存非常紧张时,即使优先回收这些对象对程序的执行正确性并不会有影响。此时,传统的Java引用就显得束手无策了。自JDK1.2后,Java引用的概念得到了新的扩展,将引用划分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。

  强引用 > 软引用 > 弱引用 > 虚引用

  强引用:Java代码中默认的引用类型就是强引用,除非实例化对象不可达,否则不会被回收。例子如下:

 Object objRef = new Object(); //objRef是一个强引用

  软引用:即使实例化对象可达,软引用的对象还是会在发生内存溢出之前(Java堆内存不够用时)被垃圾回收器回收,例子如下:

//上接之前的代码,创建一个软引用
SoftReference objSoftRef = new SoftReference(objRef); Object objRef2 = (Object)objSoftRef.get(); //如果此时软引用还未被回收,可以通过这段代码重新或得到实例化对象的强引用,否则会返回null

  弱引用:比软引用更弱,在下一次垃圾回收器收集到弱引用后对象会被回收,具体用法与软引用一致,弱引用类类名为WeakReference。

  虚引用:这个引用很特殊,其存在不影响对应的实例化对象的生命周期,也不能够通过get方法再获取到对象的强引用。与一个特殊的引用队列(ReferenceQueue)配合使用可以用于监听实例化对象的回收事件。例子如下:

//上接之前代码,创建一个引用队列
/************************************************
** 解释一下引用队列:
** 在一个实例化对象被垃圾回收器回收之前,与这个对象相关的引用对象(Java.lang.refReference类型)都会被加入到与之相关的引用队列中
*************************************************/
ReferenceQueue queue = new ReferenceQueue (); //创建一个虚引用,同时将这个虚引用与队列queue相关联
PhantomReference objPhaRef = new PhantomReference(obj,queue); assertNull(queue.poll()); obj = null; //obj对象在被回收之前,objPhaRef 对象就会被加入到queue队列中
assertNull(queue.poll());

 根搜索算法

  垃圾回收器在判定一个对象是否可以被回收时采用的是根搜索算法,基本思想:从已知的GC Roots对象开始遍历向下搜索,找到所有的可达实例化对象,回收所有不可达的实例化对象。GC Roots对象包含如下:

  虚拟机栈中的引用对象

  方法区中的静态引用对象

  常量池中的常量引用对象

  本地方法栈中的引用对象

  那么,当一个实例化对象在被确定不可达之后,会被马上“杀死”吗?

  答案是否定的,其中的例外小技巧就是在finalize()函数。为了保证c++程序员能够接受,java提供了类似于析构函数的finalize,垃圾回收器保证一个对象在被真正销毁之前必定调用过一次finalize。那么,我们就可以在这个finalize函数中再次将本对象赋值给一个外部引用,试图在真正销毁之前挽救对象。(PS:但是需要注意的是,类似于表达finalize函数并不是java中的虚构函数,它并不保证是在对象真正销毁之前被调用的最后一个函数,它只保证一个对象在被销毁之前必定会被调用过一次)。

Java杂谈2——引用与跟搜索算法的更多相关文章

  1. Java学习之强引用,弱引用,软引用 与 JVM

    1.java内存管理分为内存分配和内存回收,都不需要程序员负责. 2.垃圾回收的机制主要是看对象是否有引用指向该对象.  java对象的引用包括  强引用 软引用 弱引用 虚引用 3.强引用 是指创建 ...

  2. Java web项目引用java项目,类型找不到

    Java web项目引用java项目,类型找不到 错误信息: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapp ...

  3. Java四种引用包括强引用,软引用,弱引用,虚引用。

    Java四种引用包括强引用,软引用,弱引用,虚引用. 强引用: 只要引用存在,垃圾回收器永远不会回收Object obj = new Object();//可直接通过obj取得对应的对象 如obj.e ...

  4. 闲来无事,用Java的软引用写了一个山寨的缓存

    闲来无事,用Java的软引用写了一个山寨的缓存 博客分类: java基础 众所周知java中的引用分为 StrongReference.SoftReference.WeakReference.Phan ...

  5. Java 集合 持有引用 & WeakHashMap

    Java 集合 持有引用 & WeakHashMap @author ixenos 摘要:强引用.弱引用.WeakHashMap动态回收步骤 Reference引用对象 可获得的(reacha ...

  6. java到底是引用传递还是值传递?

    今天我们来讲讲一个在学习中容易误解的问题,面试中也偶尔问到,java方法调用时到底是值传递还是引用传递? 首先,请大家来做一个判断题,下面的3个问题是否描述正确 1. java基本数据类型传递是值传递 ...

  7. Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)

    Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...

  8. Java中的引用传递和值传递

    Java中的引用传递和值传递 关于Java的引用传递和值传递,在听了老师讲解后,还是没有弄清楚是怎么一回事,于是查了资料,所以在这里与大家分享,有不对的地方,欢迎大家留言. java中是没有指针的,j ...

  9. Java中没有引用传递只有值传递(在函数中)

    ◆传参的问题 引用类型(在函数调用中)的传参问题,是一个相当扯的问题.有些书上说是传值,有些书上说是传引用.搞得Java程序员都快成神经分裂了.所以,我们最后来谈一下“引用类型参数传递”的问题. 如下 ...

随机推荐

  1. IntValue()方法 和 ValueOf()方法

    intValue() 1.intValue()是java.lang.Number类的方法,Number是一个抽象类.Java中所有的数值类都继承它.也就是说,不单是Integer有intValue方法 ...

  2. 【洛谷 UVA11417】 GCD(欧拉函数)

    我们枚举所有gcd \(k\),求所有\(gcd=k\)的数对,记作\(f(k)\),那么\(ans=\sum_{i=1}^{n}(f(i)-1)*i\).为什么减1呢,观察题目,发现\(j=i+1\ ...

  3. wikioi 1245最小的N个和

    2013-09-08 10:12 LRJ的算法竞赛入门经典训练指南里有类似的题,原题要难很多,p189页 读入A,B两组中的所有数后,建立N个有序表: A1+B1<A2+B1<A3+B1& ...

  4. Splunk Power User认证

    课程介绍 | 通过 Splunk Fundamentals Part 1 课程考试 | 获取splunk certificate user 证书 | 课程为14节课+课后实验环境+课后习题 | 课程有 ...

  5. GridPanel分页条插件

    GridPanel的分页条没有设置当前页显示条数的功能,会不大方便 主要是抄袭的http://www.cnblogs.com/badwps/archive/2011/04/15/2016440.htm ...

  6. [Leetcode Week4]H-Index

    H-Index题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/h-index/description/ Description Given an arr ...

  7. 关于EINTR错误的理解【转】

    转自:http://www.xuebuyuan.com/1470645.html 最近在工作中遇到了EINTR错误,感到比较困惑,几番研究之后,颇有心得和收获,特记录如下,便于以后查询,也给有同样困惑 ...

  8. 3个js函数 变成数组本身的3个方法

    <!DOCTYPE html> 3个js函数 变成数组本身的3个方法 /** * 稀疏数组 变成不稀疏数组 * @params array arr 稀疏数组 * @return arry ...

  9. BAT 前端开发面经 —— 吐血总结

    更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘,在此总结一下 一是备忘.总结提升,二是希望给大家一些参考 其他面试及基础相关可以参考其他博文: ...

  10. (4)三剑客之awk

    (1)awk工作原理#awk -F: '{print $1,$3}' /etc/passwd 1)awk使用一行作为输入,并将这一行赋给内部变量$0,每一行也可称为一个记录,已换行符结束 2)然后行被 ...