博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HotSpot在GC时如何实现对象存活判断和垃圾收集
阅读量:6804 次
发布时间:2019-06-26

本文共 1145 字,大约阅读时间需要 3 分钟。

hot3.png

1. 枚举根节点

之前介绍了在GC过程中要先判断对象是否存活,用到了可达性分析算法,通过GC Roots节点找引用链。可作为GC Root的节点主要在全局性引用(例如常量和静态变量)与执行上下文(栈帧中的本地变量表)中。那么如何在这么多的全局变量和栈中的局部变量表中找到栈上的根节点呢?在栈中只有一部分数据是Reference(引用)类型,那些非Reference的类型的数据对于找到根节点没有什么用处,如果我们对栈全部扫描一遍这是相当浪费时间和资源的事情。所以要通过枚举来找到GC Roots根节点。

可达性分析对执行时间是敏感的,体现在GC停顿上,该分析过程中不能出现对象引用关系还在不断变化的情况,这导致了GC进行时必须停顿所有Java执行线程,因此枚举根节点时也是必须要停顿的。

目前主流的Java虚拟机用的都是准确式GC,当系统停顿后不需要全局扫面引用位置,借助OopMap这种数据结构,虚拟机可以直接得知哪些地方存放着对象引用,因此可以快速完成枚举根节点。

2. 安全点

OopMap内容变化的指令很多,不能为每一条指令都生成对应的OopMap,HotSpot虚拟机是在特定位置生成了OopMap,这些位置叫做“安全点”。程序执行时只有到了安全点才会暂停下来开始GC。一般具有“长时间执行”这个特点的指令(例如方法调用、循环跳转、异常跳转)才会产生安全点。

如何在GC时让所有线程都跑到安全点上再停顿下来?两种方案:

(1) 抢先式中断。(现在几乎没有虚拟机采用该方法)

不需要线程主动配合,在GC发生的时候就让所有线程都中断,如果发现哪个线程中断的地方不在安全点上,那么就恢复线程,然后让它跑到安全点上。

(2) 主动式中断

GC在需要中断线程的时候不直接对线程操作,设置一个标志,让各个线程主动轮询这个标志,如果中断标志位真时就让自己中断。

3. 安全区域

使用“安全点”似乎完美解决了如何进入GC的问题,安全点机制保证了程序执行时在不太长的时间内就会遇到安全点,从而进入GC。但是当程序不执行的时候(即当线程处于Sleep或者Blocked状态),线程无法响应JVM的中断请求而走到安全点去中断挂起,JVM也不会等待线程重新被唤醒,这时就需要安全区域来解决。

安全区域是指在一段代码片段中,引用关系不会发生变化,在该区域的任何地方发生GC都是安全的。当代码执行到安全区域时,首先标识自己已经进入了安全区域,那样如果在这段时间里JVM发起GC,就不用管标识自己在安全区域的那些线程了,在线程离开安全区域时,会检查系统是否正在执行GC,如果是那么就等到GC完成后再离开安全区域。

转载于:https://my.oschina.net/edwardge/blog/1801545

你可能感兴趣的文章
简单优化容器服务
查看>>
PHP从二维数组获取指定数据,组成新维二数组
查看>>
TCP详解
查看>>
重学ES6 数组扩展(2)
查看>>
Netty3的入门案例
查看>>
你会这道阿里多线程面试题吗?
查看>>
行云管家V4.9正式发布:监控全面提升,首页、主机详情大幅优化,新增大量实用功能.md...
查看>>
采用镜像部署LNMP 环境操作步骤
查看>>
不服?来跑个分!
查看>>
Python笔记 开发环境搭建
查看>>
ios logo 启动页大小
查看>>
(四)构建dubbo分布式平台-maven代码结构
查看>>
Vue插件从封装到发布
查看>>
扒一扒我们生活中常见的品牌小程序
查看>>
使用注解干掉大量if else和switch
查看>>
【本人秃顶程序员】实战并发-使用分布式缓存和有限状态机
查看>>
[MySQL光速入门]019 分别使用loop, while, repeat 来计算 从0加到100 答案
查看>>
浅析libuv源码-node事件轮询解析(2)
查看>>
区块链软件公司:区块链技术去中心化
查看>>
Python爬虫的基本概念、分类、学习路线以及爬取数据思路
查看>>