1.枚举根节点

  在可达性分析中,可以作为GC Roots的节点有很多,但是现在很多应用仅仅方法区就有上百MB,如果逐个检查的话,效率就会变得不可接受。

  而且,可达性分析必须在一个一致性的快照中进行-即整个分析期间,系统就像冻结了一样。否则如果一边分析,系统一边动态表化,得到的结果就没有准确性。这就导致了系统GC时必须停顿所有的Java执行线程。

  目前主流Java虚拟机使用的都是准确式GC,所以当执行系统都停顿下来之后,并不需要一个不漏的检查完所有执行上下文和全局的引用位置,虚拟机应该有办法直接知道哪些地方存放着对象引用。在HotSpot实现中,使用一组称为 OopMap 的数据结构来达到这个目的。OopMap会在类加载完成的时候,记录对象内什么偏移量上是什么类型的数据,在JTI编译过程中,也会在特定的位置记录下栈和寄存器哪些位置是引用。这样,在GC扫描的时候就可以直接得到这些信息了。

2.安全点

  如果OopMap内容变化的指令非常多,HotSpot并不会为每条指令都产生OopMap,只是在特定的位置记录了这些信息,这些位置成为“安全点”(SafePoint)。程序执行时只有在达到安全点的时候才停顿开始GC。一般具有较长运行时间的指令才能被选为安全点,如方法调用、循环跳转、异常跳转等。

  接下来要考虑的便是,如何在GC时保证所有的线程都“跑”到安全点上停顿下来。这里有两种方案: 抢先式中断 (Preemptive Suspension) 和主动式中断 (Voluntary Suspension)。

  抢先式中断会把所有线程中断,如果某个线程不在安全点上,就恢复线程让它跑到安全点上。几乎没有虚拟机采用这种方式。

  主动式中断思想是需要中断线程时,不直接对线程操作,而是设置一个GC标志,各个线程会轮询这个标志并在需要时自己中断挂起。这样,轮询标志的地方和安全点是重合的。

3.安全区域

  安全点机制保证程序执行时,在不太长的时间内就会遇到可进入GC的安全点,但是,程序“不执行”的时候呢,程序不执行就是没有分配CPU时间,这时线程无法响应JVM的中断请求,JVM显然不太可能的等待线程重新被分配CPU时间。

  安全区域是指一段代码片段之中,引用关系不会发生变化。在这个区域中的任意地方开始GC都是安全的。

  在线程执行到安全区域代码时,首先标识自己进入安全区域,当这段时间里JVM发起GC,不用管标识为安全区域的线程了。在线程要离开安全区域时,要检查系统是否已经完成了根节点枚举,如果完成,线程继续执行,否则等待直到收到可以安全离开安全区域的信号为止。

5.HotSpot的算法实现的更多相关文章

  1. HotSpot关联规则算法(2)-- 挖掘连续型和离散型数据

    本篇代码可在 http://download.csdn.net/detail/fansy1990/8502323下载. 前篇<HotSpot关联规则算法(1)-- 挖掘离散型数据>分析了离 ...

  2. HotSpot的算法实现

    1.枚举根节点 可达性分析中从GC Roots节点找引用,可作为GC Roots的节点主要是全局性的引用与执行上下文中,如果要逐个检查引用,必然消耗时间.另外可达性分析对执行时间的敏感还体现在GC停顿 ...

  3. JVM·垃圾收集器与内存分配策略之垃圾回收算法!

    1.垃圾回收算法    1.1.标记-清除算法(Mark-Sweep):             过程分为“标记”和“清除”两个过程.先将所有需要回收的目标统一标记,然后再统一清除.          ...

  4. JVM内存分配策略,及垃圾回收算法

    本人免费整理了Java高级资料,一共30G,需要自己领取;传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 说起垃圾收集(Garbage Co ...

  5. 【JVM】JVM系列之垃圾回收(二)

    一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...

  6. 深入理解JVM-3垃圾收集器与内存分配策略

    在上面一篇文章中,介绍了java内存运行时区域,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程生灭:栈中的栈帧随着方法的进入和退出而有条不紊的执行着进栈出栈的操作,每一个栈帧中分配着多少内存基本上 ...

  7. JVM-对象的存活与死亡

    当Java虚拟机进行垃圾收集的时候,那么它必须要先判断对象,是否还存活,如果存活就不能对它进行回收.所以判断一个对象是否存活是Java虚拟机必须要实现的. 1.对象是否存活 1)引用计数器:给对象添加 ...

  8. 深入理解Java虚拟机--上

    深入理解Java虚拟机--上 第2章 Java内存区域和内存溢出异常 2.2 运行时数据区域 图 2-1 Java虚拟机运行时数据区 2.2.1 程序计数器 程序计数器可以看作是当前线程所执行的字节码 ...

  9. 《深入理解Java虚拟机:JVM高级属性与最佳实践》读书笔记(更新中)

    第一章:走进Java 概述 Java技术体系 Java发展史 Java虚拟机发展史 1996年 JDK1.0,出现Sun Classic VM HotSpot VM, 它是 Sun JDK 和 Ope ...

随机推荐

  1. 转 https://www.zhihu.com/question/27606493/answer/37447829

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:梁川链接:https://www.zhihu.com/question/27606493/answer/37447829来源: ...

  2. bzoj1513: [POI2006]Tet-Tetris 3D

    Description Task: Tetris 3D "Tetris" 游戏的作者决定做一个新的游戏, 一个三维的版本, 在里面很多立方体落在平面板,一个立方体开始落下直到碰上一 ...

  3. AngularJS 中利用 Interceptors 来统一处理 HTTP 的错误(reproduce)

    原文:http://chensd.com/2016-03/Angular-Handle-Global-Http-Error-with-Interceptors.html?utm_source=tuic ...

  4. CRM JS 设置lookup字段 setSimpleLookupValue

    function setSimpleLookupValue(LookupId, Type, Id, Name) { /// <summary> /// Sets the value for ...

  5. 母版页的 page_load事件执行两次

    定义了一个母版页 Admin.master  部分代码如下 <body onload="LoadHight()"> <div> <!--公共的头部开始 ...

  6. delphi 调用c#dll

    public interface iProduct { string Buy(); } [ClassInterface(ClassInterfaceType.None)] public class P ...

  7. java 中小数点的处理

    第一种 BigDecimal bg = new BigDecimal(f); double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleVa ...

  8. eclipse与myeclipse恢复已删除的文件和代码

    1.类文件的恢复 选择项目后右键-->选择Restore from Local history-->出现下面的界面: 勾选后按Restore就恢复了,真的很强大很方便:但我没有就此罢手,我 ...

  9. http://www.cnblogs.com/20135131zxy/

    一.实验内容 1. 使用JDK编译.运行简单的Java程序 2.使用Eclipse 编辑.编译.运行.调试Java程序 二.实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门( ...

  10. WEB服务器、应用程序服务器、HTTP服务器区别

    很清晰的解释了WEB服务器.应用程序服务器.HTTP服务器区别 转载自 http://www.cnblogs.com/zhaoyl/archive/2012/10/10/2718575.html WE ...