HotSpot的算法实现
1.枚举根节点
可达性分析中从GC Roots节点找引用,可作为GC Roots的节点主要是全局性的引用与执行上下文中,如果要逐个检查引用,必然消耗时间。另外可达性分析对执行时间的敏感还体现在GC停顿上,因为这项分析工作必须在一个能确保一致性的快照中进行——这里的“一致性”的意思是指整个分析期间整个系统执行系统看起来就行被冻结在某个时间点,不可以出现分析过程中对象引用关系还在不断变化的情况,该点不满足的话分析结果的准确性就无法得到保证。这点是导致GC进行时必须暂停所有Java执行线程的其中一个重要原因。
由于目前主流的Java虚拟机都是准确式GC,所以当执行系统停顿下来之后,并不需要一个不漏的检查执行上下文和全局的引用位置,虚拟机应当有办法得知哪些地方存放的是对象的引用。在HotSpot的实现中,是使用一组OopMap的数据结构来达到这个目的的。OopMap会在类加载完成的时候,记录对象内什么偏移量上是什么类型的数据,在JTI编译过程中,也会在特定的位置记录下栈和寄存器哪些位置是引用。这样,在GC扫描的时候就可以直接得到这些信息了。
2.安全点
在OopMap的协助下,HotSpot可以快速且准确的完成GC Roots的枚举,但可能导致引用关系变化的指令非常多,如果为每一条指令都生成OopMap,那将会需要大量的额外空间,这样GC的空间成本会变的很高。实际上,HotSpot也的确没有为每条指令生成OopMap,只是在特定的位置记录了这些信息,这些位置被称为安全点(SafePoint),即程序执行时并非在所有的地方都能停顿下来执行GC,只能在到达安全点时才能暂停。SafePoint的选定既不能太少,以致让GC等待时间太久,也不能设置的太频繁以至于增大运行时负荷。所以安全点的设置是以让程序“是否具有让程序时间执行的特征”为标准选定的。“长时间执行”最明显的特征就是指令序列的复用,例如方法调用、循环跳转、异常跳转等,所以具有这些功能的指令才会产生 SafePoint。
对于SafePoint,另一个问题是如何在GC发生时让所有线程都跑到安全点在停顿下来。这里有两种方案:抢先式中断和主动式中断。抢先式中断不需要线程代码主动配合,当GC发生时,首先把所有线程中断,如果发现线程中断的地方不在安全点上,就恢复线程,让他跑到安全点上。现在几乎没有虚拟机实现采用抢先式中断来暂停线程来响应GC。而主动式中断的思想是当GC需要中断线程的时候,不直接对线程操作,仅仅简单的设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标志为真时就自己中断挂起,轮询标志的地方和安全点是重合的,另外再加上创建对象需要分配的内存的地方。
3.安全区域
使用安全点似乎已经完美解决了如何进入GC的问题,但实际情况却并不一定,安全点机制保证了程序执行时,在不太长的时间内就会进入到可进入的GC的安全点。但是程序如果不执行呢?所谓的程序不执行就是没有分配cpu时间,典型的例子就是线程处于sleep状态或者blocked状态,这时候线程无法响应 jvm中断请求,走到安全的地方中断挂起,jvm显然不太可能等待线程重新分配cpu时间,对于这种情况,我们使用安全区域来解决。
安全区域是指在一段代码片段之中,引用关系不会发生变化。在这个区域的任何地方开始GC都是安全的,我们可以把安全区域看做是扩展了的安全点。当线程执行到安全区域中的代码时,首先标识自己已经进入了安全区,那样当在这段时间里,JVM要发起GC时,就不用管标识自己为安全区域状态的线程了。当线程要离开安全区域时,他要检查系统是否完成了根节点枚举,如果完成了,那线程就继续执行,否则他就必须等待,直到收到可以安全离开安全区域的信号为止。
HotSpot的算法实现的更多相关文章
- HotSpot关联规则算法(2)-- 挖掘连续型和离散型数据
本篇代码可在 http://download.csdn.net/detail/fansy1990/8502323下载. 前篇<HotSpot关联规则算法(1)-- 挖掘离散型数据>分析了离 ...
- 5.HotSpot的算法实现
1.枚举根节点 在可达性分析中,可以作为GC Roots的节点有很多,但是现在很多应用仅仅方法区就有上百MB,如果逐个检查的话,效率就会变得不可接受. 而且,可达性分析必须在一个一致性的快照中进行-即 ...
- JVM·垃圾收集器与内存分配策略之垃圾回收算法!
1.垃圾回收算法 1.1.标记-清除算法(Mark-Sweep): 过程分为“标记”和“清除”两个过程.先将所有需要回收的目标统一标记,然后再统一清除. ...
- JVM内存分配策略,及垃圾回收算法
本人免费整理了Java高级资料,一共30G,需要自己领取;传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 说起垃圾收集(Garbage Co ...
- 【JVM】JVM系列之垃圾回收(二)
一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收.除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此.所以,垃圾回收是必须的. 二. ...
- 深入理解JVM-3垃圾收集器与内存分配策略
在上面一篇文章中,介绍了java内存运行时区域,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程生灭:栈中的栈帧随着方法的进入和退出而有条不紊的执行着进栈出栈的操作,每一个栈帧中分配着多少内存基本上 ...
- JVM-对象的存活与死亡
当Java虚拟机进行垃圾收集的时候,那么它必须要先判断对象,是否还存活,如果存活就不能对它进行回收.所以判断一个对象是否存活是Java虚拟机必须要实现的. 1.对象是否存活 1)引用计数器:给对象添加 ...
- 深入理解Java虚拟机--上
深入理解Java虚拟机--上 第2章 Java内存区域和内存溢出异常 2.2 运行时数据区域 图 2-1 Java虚拟机运行时数据区 2.2.1 程序计数器 程序计数器可以看作是当前线程所执行的字节码 ...
- 《深入理解Java虚拟机:JVM高级属性与最佳实践》读书笔记(更新中)
第一章:走进Java 概述 Java技术体系 Java发展史 Java虚拟机发展史 1996年 JDK1.0,出现Sun Classic VM HotSpot VM, 它是 Sun JDK 和 Ope ...
随机推荐
- Linux线程的创建
一.线程与进程的区别 1.线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源. 2.进程是资源分配的基本单位.所有与该进程有关的资源,都 ...
- Linux网络那点事
跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 之前的之前说过网络自连接的配置(CentOS服务器网络配置:http://ww ...
- 搭建ubuntu版hadoop集群
用到的工具:VMware.hadoop-2.7.2.tar.jdk-8u65-linux-x64.tar.ubuntu-16.04-desktop-amd64.iso 1. 在VMware上安装ub ...
- Myeclipse8.5开发-程序发布
1.新建focus.xml文件. 2.添加如下内容 <Context path="/focus" docBase="F:\Workspaces\MyEcli ...
- [转]android4.0.3 修改启动动画和开机声音
本文转自:http://www.cnblogs.com/jqyp/archive/2012/03/07/2383973.html 1. Linux 系统启动,出现Linux小企鹅画面(reboot)( ...
- 关于html5调用手机相机(原创)
很久没写随笔了 从ios6开始,webview支持html <input type="file">标签,用来调取手机的相册和相机,但是没有权限提示,不知道是不是我写的有 ...
- Nginx基础学习(一)—Nginx的安装
一.Nginx介绍 1.什么是Nginx? Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.由俄罗斯的程序设计师Igor Sysoev所开 ...
- 通过UDP广播实现Android局域网Peer Discovering
本文是对个人笔记中内容的整理,部分代码及图片来自互联网,由于不好找到原始出处,所以未加注明. 如有痛感,联系删除. 本文将介绍以下知识点: TCP与UDP的区别: 单播.多播.广播: Java中实现U ...
- python类与对象基本语法
面向对象编程的2个非常重要的概念:类和对象. 对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念--类. 类就相当于制造飞机时的图纸,用它 ...
- 基于Flink的windows--简介
新的一年,新的开始,新的习惯,现在开始. 1.简介 Flink是德国一家公司名为dataArtisans的产品,2016年正式被apache提升为顶级项目(地位同spark.storm等开源架构).并 ...