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. Sencha Touch MVC 中 store 的使用

    I have a UserStore that I want to load after succesful login of a user. I can't get this to work i.e ...

  2. OWNER:Java配置文件解决方案 使用简介

    这个感觉还是很方便的一个工具.  学习网站是:http://hao.jobbole.com/owner/ 测试步骤: 1.pom <dependency> <groupId>o ...

  3. oracle查看字符集和修改字符集

    oracle查看字符集和修改字符集 : 查看数据库服务器的字符集: select userenv('language') from dual ; 登陆用dba: 停掉数据库 : shutdown im ...

  4. css划斜线

    http://stackoverflow.com/questions/18012420/draw-diagonal-lines-in-div-background-with-css

  5. 【poj3260-最少找零】多重背包+完全背包

    多重背包+完全背包. 买家:多重背包:售货员:完全背包: 开两个数组,分别计算出买家,售货员每个面额的最少张数. 最重要的是上界的处理:上界为maxw*maxw+m(maxw最大面额的纸币). (网上 ...

  6. bzoj3779: 重组病毒 link-cut-tree

    题目传送门 这道题看了做了个神转换.....推荐个博客给各位大爷看看吧神犇传送门 代码敲了半天....题目也读了半天 线段树维护的东西很容易和lct混在一起 调了调能过也是很开心啊 运气比较好吧233 ...

  7. 【洛谷 P2464】[SDOI2008]郁闷的小J(线段树)

    题目链接 这题我很久之前用分块写过,没写出来.. 今天又看到了,于是下决心把这题做出来. 这次我用线段树写的,直接对每本书的编号Hash一下然后离散化然后各建一棵线段树,维护当前编号在某个位置有没有书 ...

  8. Node.js 编码转换

    Node.js自带的toString()方法不支持gbk,因此中文转换的时候需要加载第三方库,推荐以下两个编码转换库,iconv-lite和encoding.       iconv, iconv-l ...

  9. linux驱动学习(二) Makefile高级【转】

    转自:http://blog.csdn.net/ghostyu/article/details/6866863 版权声明:本文为博主原创文章,未经博主允许不得转载. 在我前一篇写的[ linux驱动学 ...

  10. ARM 处理器架构【转】

    ARM 处理器架构 转自:http://www.arm.com/zh/products/processors/instruction-set-architectures/index.php ARM 架 ...