jvm在判断对象死亡之前需要判断对象是否可到达,方法有引用计数算法和可达性分析算法,jvm采用的是后者.首先来了解一下这两种算法.

引用计数算法:

算法定义

为每个对象增加一个字段记录被引用的次数,并由运行时跟踪和更新引用的总数;

object p = new ComparableInt32(57);

object q = p;

我们实例化了一个对象ComparableInt32,并将其赋值给变量p,此时p引用了该对象,所以其计数器为1;然后我们又用p给变量q赋值,此时q也引用了该变量,所以其计数器变为2;如下图所示

从上图我们可以看到,引用类型每次赋值都需要运行时更新计数器,运行时的更新代码可能如下

if (p != q)

{

         if (p != null)

                   --p.refCount;

         p = q;

         if (p != null)

                   ++p.refCount;

}

计数器算法的一大优势就是不用等待内存不够用的时候,才进行垃圾的回收,其可以在赋值操作的同时,检查计数器是否为0,如果是的话就可以立即回收;运行时的代码可能如下

if (p != q)

{

         if (p != null)

                   if (--p.refCount == 0)

                            heap.Release(p);

         p = q;

         if (p != null)

                   ++p.refCount;

}

计数器算法的一大缺点就是不能解决循环引用的问题;如下图,我们构造了一个列表,我们将最后一个元素的next属性指向第一个元素,即引用第一个元素,从而构成循环引用;这个时候如果我们将列表的头head赋值为null,此时列表的各个元素的计数器都不为0,同时我们也失去了对列表的引用控制,从而导致列表元素不能被回收!

可达性分析算法:

算法特点

1.       需要单独的字段存储计数器,增加了存储空间的开销;

2.       每次赋值都需要更新计数器,增加了时间开销;

3.       垃圾对象便于辨识,只要计数器为0,就可作为垃圾回收;

4.       及时回收垃圾,没有延迟性;

5.       不能解决循环引用的问题;

在主流的商用程序语言(Java、C#,甚至包括前面提到的古老的Lisp)的主流实现中,都是称通过可达性分析(Reachability Analysis)来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如图3-1所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

在Java语言中,可作为GC Roots的对象包括下面几种:

虚拟机栈(栈帧中的本地变量表)中引用的对象。

方法区中类静态属性引用的对象。

方法区中常量引用的对象。

本地方法栈中JNI(即一般说的Native方法)引用的对象。

在确定对象不可到达之后,该对象并不会立刻被释放,jvm会判断该对象是否有finalize()方法,若有,则开启一个优先级较低的线程去执行这个方法.如果在执行的过程中,该对象又与引用链上的其他对象建立了关联,则该对象便获得重生,不会被释放.否则,在执行之后被jvm释放.

不过每个对象的finalize()方法仅能执行一次,若一个对象在第一次GC时已经执行了finalize()方法,且获得了重生,则下一次GC时若该对象为不可到达,则直接被释放.(建议:尽量不要使用finalize()方法).

jvm回收对象的更多相关文章

  1. JVM 垃圾回收机制( 一) 回收对象的判定

    关于JVM 的垃圾回收机制,我们一般都没过多深入,因为JAVA 和 C++ 的一个很大区别就是,JAVA 帮我们做了垃圾回收,而不用像C++ 那么样手动进行回收,当然任何自动的东西都存在一定弊端,比如 ...

  2. JVM中对象的回收过程

      当我们的程序开启运行之后就,就会在我们的java堆中不断的产生新的对象,而这是需要占用我们的存储空间的,因为创建一个新的对象需要分配对应的内存空间,显然我的内存空间是固定有限的,所以我们需要对没有 ...

  3. JVM之对象回收

    finalize /** *此代码演示了两点: *1.对象可以在被GC时自我拯救. *2.这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次 */ public ...

  4. (转)Java回收对象的标记 和 对象的二次标记过程

    Java回收对象的标记 和 对象的二次标记过程 二次标记 针对这个问题,虚拟机的做法是进行两次标记,即第一次标记不在“关系网”中的对象.第二次的话就要先判断该对象有没有实现finalize()方法了, ...

  5. Java虚拟机笔记(五):JVM中对象的分代

    为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...

  6. 深入探究JVM之对象创建及分配策略

    @ 目录 前言 正文 一.对象的创建方式 二.对象的创建过程 对象在哪里创建 分配内存 对象的内存布局 三.对象的访问定位 四.判断对象的存活 对象生死 回收方法区 引用 对象的自我拯救 五.对象的分 ...

  7. JVM中对象的创建过程

    JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...

  8. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第5节: 同线程回收对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第五节: 同线程回收对象 上一小节剖析了从recycler中获取一个对象, 这一小节分析在创建和回收是同线程的 ...

  9. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第6节: 异线程回收对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第六节: 异线程回收对象 异线程回收对象, 就是创建对象和回收对象不在同一条线程的情况下, 对象回收的逻辑 我 ...

随机推荐

  1. webkit内核下的mouseup后mousemove自动触发问题及解决方法

    如题,就以chrome为代表举例说明遇到mousemove的问题. 为body分别绑定onmousedown.onmousemove.onmouseup,并为触发时打印至控制台.代码如下(同学不要忘记 ...

  2. elasticsearch集群搭建实例

    elasticsearch集群搭建实例 下个月又开始搞搜索了,几个月没动这块还好没有落下. 晚上在自己虚拟机上搭建了一个简易搜索集群,分享一下. 操作系统环境: Red Hat 4.8.2-16 el ...

  3. jQuery Easy UI LinkButton(button)包

    LinkButton(button)包,easyui其中一个基本组成部分 演示样例: <!DOCTYPE html> <html> <head> <title ...

  4. 实例学习SSIS(二)--使用迭代

    原文:实例学习SSIS(二)--使用迭代 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SSIS(四)-- ...

  5. javascript this指针指向?

    前言 理解javascript的指针就需要先了解js的执行环境和作用域!执行环境的定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有的变 ...

  6. 设置符合条件的DataGridView的行的颜色的两种方法

    Private Sub dgvInfo_RowPrePaint(sender As Object, e As DataGridViewRowPrePaintEventArgs) Handles dgv ...

  7. PhotoShop基本工具 -- 移动工具

    艺术或学习的东西吧, 爱好   比学编程还难 PS版本号 : PhotoShop CS6 1. 移动工具 (1) 工具栏和属性栏 工具栏 和 属性栏 : 左側的是工具栏, 每选中一个工具, 在菜单条的 ...

  8. C#/ASP.NET/AJAX

      C#/ASP.NET/AJAX ASP.NET 4.5新特性一:强类型数据绑定(Strongly-Type Data-Bindings) 摘要: 随着ASP.NET 4.5的发布提供了很多的新特性 ...

  9. 实现Client Credentials Grant

    [OAuth]基于DotNetOpenAuth实现Client Credentials Grant   Client Credentials Grant是指直接由Client向Authorizatio ...

  10. linux网卡驱动安装及锐捷使用

    原创博文,转载请注明出处 先吐槽一下,以前装了个Centos win7双系统, 然后手贱一不小心把启动文件给删了,接下来就用grub恢复启动文件,整了一天也没搞出来还把win7的Boot Manage ...