zoukankan      html  css  js  c++  java
  • 垃圾收集器与内存分配策略(三)之HotSpot的算法实现

    垃圾收集器与内存分配策略(三)——HotSpot的算法实现

      在HotSpot虚拟机上实现这些算法时,必须对算法的执行效率有着严格的考量,才能保证虚拟机高效地运行。

    1、 枚举根节点

      采用可达性分析从GC Roots节点中找引用链为例

      存在的缺点:
      1、在前面找出还存活对象时,采用可达性分析从GC Roots节点中找引用链时,可作为GC Roots的节点主要在全局性的引用(方法区的常量或类静态属性引用)与执行上下文(虚拟机栈栈帧中的本地变量表或本地方法栈中的Native方法的引用)中,很多应用仅仅方法区就有数百兆,如果要逐个检查这里面的引用,必然会消耗很多时间。

      2、可达性分析对时间的敏感还体现在GC停顿上,因为这项工作必须在一个能确保一致性的快照中进行。“一致性值的是”GC进行时必须停顿所有Java执行线程(Stop The World)。

      HotSpot的解决方式
      1、当执行系统停下来时,不需要检查完所有的全局和执行上下文的引用位置,HotSpot采用一组称为OopMap的数据结构来记录那些地方存放着对象的引用。

      2、JIT(即时编译)编译过程中也会在特定位置记录下栈和寄存器中那些位置是引用。

    2、 安全点

      如果为每一条指令都生成对应的Oopmap,会需要大量的额外空间,GC成本增高。其实HotSpot虚拟机并不是在为每条指令都生成了Oopmap,程序执行时也并非在任何地方都能停下来开始GC,只能到达特定位置才能开始记录,这些特定位置称为安全点(Safepoint)。

      安全点的选择:是否具有让程序长时间执行的特征(比如:方法调用,循环跳转,异常跳转等)。

      在GC发生时如何让所有线程跑到最近的安全点再停止有二种方案:

      1、抢先式中断:不需要线程的执行代码主动去配合,在GC发生时,首先把所有线程全部中断,如果发现有线程中断的地方不在安全点上,就恢复线程,让它“跑”到安全点上。 现在几乎没有虚拟机实现采用抢先式中断来暂停线程从而响应GC事件。

      2、主动式中断:当GC需要中断线程的时候,不直接对线程操作,仅仅简单地设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标志为真时就自己中断挂起。轮询标志的地方和安全点是重合的,另外再加上创建对象需要分配内存的地方。

    3、 安全区域

      当程序不执行的时候即没有分配CPU时间,比如:线程处于Sleep状态或Blocked状态,对于这种情况就需要安全区域(Safe Region)来解决。

      安全区域指在一段代码片段中,引用关系不会发生变化。在这个区域的任意地方开始GC都是安全的,或则可以将安全区域看做时扩展过得安全点。

      安全区域工作原理:在线程中执行到安全区域的代码时,首先标识自己已经进入了安全区域,若在这段时间JVM要发起GC时,就不用管标识自己为安全区域状态的线程了。在线程执行完安全区域的代码要离开安全区域时,当前线程要检查当前系统是否已经完成了根节点枚举(或是整个GC过程),若系统已完成则可以离开安全区域;若系统未完成,则它就必须等待直到可以离开安全区域为止。

  • 相关阅读:
    【SSM电商项目后台开发】004-用户模块
    【SSM电商项目后台开发】003-项目架构概览
    C#面向对象编程「字段与属性」
    C#基本语法
    C#学习笔记-简介
    软件工程团队作业展示
    “消灭选择困难症”软件设计规格说明书
    “消灭选择困难APP”软件需求规格说明书
    消灭选择困难APP
    消灭选择困难
  • 原文地址:https://www.cnblogs.com/0427mybirthday/p/7264374.html
Copyright © 2011-2022 走看看