您的位置:首页 > 编程语言 > Java开发

JVM读书笔记之对象的生存或死亡

2017-10-18 09:23 106 查看
       莎士比亚说过:生存还是死亡这是一个问题?我们在进行JVM语言进行编程不需要考虑内存释放问题,因为JVM会帮助我们进行GC(垃圾回收),如此说来,JVM是如何判断对象的生存与死亡,哪些内存需要进行回收。在学习JVM垃圾回收之前,我们必须了解JVM如何判断对象的生存与死亡。

     一. 判断方法

      Java堆中几乎存放着Java世界中所有对象实例,垃圾收集器在对堆进行回收之前,第一件事请就是确定对象的存活与死亡。现阶段有以下两种主流方法判断。

     1. 引用计数法

            给每个对象添加一个引用计数器,对象被引用则+1,引用失效-1。任何时刻计数器为0的对象都是不可能再被使用的。它实现简单,判定效率高,但是Java语言没有使用,其中最主要原因是很难解决对象之间的相互循环引用问题。例如:ObjectA.instance = ObjectB; ObjectB.instance = ObjectA;除此之外,两个对象再无任何引用,实际上两个对象都不可能再被访问,但是它们互相引用着对方,导致它们的引用计数都不为0,于是GC算法无法对它们进行回收。

     2. GC Root Tracing

           主流商业应用程序语言(java,C#)都使用该算法。基本思路是通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链,则证明这个对象是不可用的。

                                           

          在Java语言中,可以作为GC roots的对象包括:

虚拟机栈(栈帧中的本地变量表)中的引用对象
方法区中的类静态变量属性的引用对象
方法区中常量引用对象
本地方法栈中JNI(Java Native Interface)的引用对象
     二. 引用的概念
           无论是引用计数法还是根搜索算法都与引用息息相关。JDK1.2后java将引用分为Strong reference、Soft reference、week reference、Phantom reference四种。
强引用:指程序代码普遍存在的,比如 A a = new A( );只要强引用还存在,GC不会回收掉被引用对象。
软引用:描述一些还有用的,但是并非必须的对象。在系统将要发生内存溢出异常前,会把这些对象列入回收范围,进行二次型回收,如果内存依旧不够,会抛出内存溢出异常。JDK提供softReference类来进行实现
弱引用:表述非必须对象,强度比软引用弱。只能生存到下次GC之前,此时无论内存是否足够都会被回收。JDK提供WeakReference类来实现。
虚引用:所有引用中最弱的一种引用关系,一个对象是否存在虚引用,不会对其生存时间构成影响,也不会通过虚引用来取得一个对象的实例。
     三. 生存还是死亡
           在根搜索算法中不可达对象,并非立即被销毁,而是处于“缓刑”阶段,至少需要经历两次标记过程:1.对象在根搜索算法中,没有GC Roots与之相连,那么它将会被第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalize( )方法(1.当对象没有覆盖finalize()方法;2.finalize()已经被虚拟机调用过。则不执行)。2.如果被判定为有必要执行finalize( )方法,则被放置到F-Queue队列中,并稍后由一条虚拟机自动建立的,低优先级的Finalizer线程去执行,进行第二次标记,如果对象在finalize()方法中重新与引用链上的任何一个对象建立关联,则它将被移除F-Queue;如果没有逃脱,那么马上就被回收。
           
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息