Java核心技术讲解学习四

上一节我们探讨了垃圾回收算法,简单的了解下垃圾回收在程序虚拟机中是怎样运行的。我们平常在开发中经常用的虚拟机是HotSpot,那么该虚拟机是怎样实现的呢?

HotSpot 算法的实现

我们知道在对象创建时候都会形成一条链,我们的可达性分析就是从GC Root节点上找引用的,其中这个节点主要是在全局性的引用于与执行上下文中。由于以下原因导致。我们现在虚拟机大部分使用的是准确式GC

  • 现在程序很多数据都是在数百M设置是数百GB,如果还要逐个检查每个引用,就容易出现问题。性能损失很多。
  • 还有一点就是可达性分析还对GC停顿敏感。

准确式GC,不需要逐个检查每个节点数据,虚拟机有自己的方法指导数据存放在哪里。HotSpot 采用的是OopMap的数据结构来实现的。在进行JIT编译时,会在特定位置记录下栈和寄存器中哪些位置是引用,等GC扫描的时候可以直接得到这些信息。

安全点

上面所说我们使用OopMap来实现引用的查找,并且还有在特定的位置记录该信息,这条信息就是安全点。并且由于安全点的存在,我们也没有必要为每条指令生成OopMap。当gc执行到安全点的时候才会停顿下来。

安全点的选择在程序中为了保持程序执行的稳定性,选定安全点一般不能太少让gc等待之间过长,但是也不能太频繁增加系统的运行负载。这样情况下 向方法调用,循环跳转,异常跳转这些点容易产生安全点。

说完对于某个点的gc,那么在gc的时候虚拟机不能一遇到安全点就去执行gc,那么十分容易导致gc平凡,甚至让程序无法执行下去。所以在GC的时候一般会选择让所有线程都跑到安全点的时候在停顿下来。其中业界采用了两种方案:抢先式中断和主动式中断。

  • 抢先式中断:会让所有的线程全部中断,但是如果有的线程不是停在安全点就恢复其跑到安全点,在进行中断。
  • 主动式中断:gc需要中断的时候,不直接对线程操作。就是设置一个标志,当执行到标志位时判断为真就自己中断挂起。

安全区域

安全点让我们发现程序在执行的时候进行gc情况,但是如果长时间不执行呢?这样就无法进行到安全点,就无法执行jvm的中断请求。在这种情况下出现了安全区域。

  • 安全区域:在一段代码中引用关系不会发生变化,在这个区域中的任意地方开始GC都是安全的。。安全区域其实是安全点的衍生。

当程序执行到安全区域时,先标识自己进入安全区域,当jvm需要挂起GC时,直接处理标识安全区域的线程代码。在离开安全区域时某系统会检查是否完成GC活动,没有执行完毕需要等待gc完成在进行线程活动,执行完毕就让线程离开安全区域继续执行即可。

原文发布于微信公众号 - LuckQI(YoungRUIQ)

原文发表时间:2018-05-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术栈大杂烩

H5: 表单验证失败的提示语

    前端的童鞋在写页面时, 都不可避免的总会踩到表单验证这个坑. 这时候, 我们就要跪了, 因为要写一堆js来检查. 但是自从H5出现后, 很多常见的表达验...

2322
来自专栏偏前端工程师的驿站

Java魔法堂:找外援的利器——Runtime.exec详解

一、前言                                  Java虽然五脏俱全但总有软肋,譬如获取CPU等硬件信息,当然我们可以通过JNI调用...

21710
来自专栏13blog.site

Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

前言   在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录。本文就是写一下发现问题的过程及解决方法...

3385
来自专栏风口上的猪的文章

.NET面试题系列[17] - 多线程概念(2)

当我们创建了一个线程后,线程里面主要包括线程内核对象、线程环境块、1M大小的用户模式栈和内核模式栈。

4542
来自专栏北京马哥教育

Python imports指南

来源:Python程序员 ID:pythonbuluo 声明:如果你每天写Python,你会发现这篇文章中没有新东西。 这是专为那些像运维人员等偶尔使用Pyt...

2595
来自专栏安恒网络空间安全讲武堂

Python编写渗透工具学习笔记一 | 0x03用多线程扫描某一网段中存活的主机

0x03用多线程扫描 某一网段中存活的主机 (如果渗透进了内网,还可以扫描内网上里的存活主机) 脚本利用演示+实现思路分析 实现思路: 调用终端执行ping命令...

28610
来自专栏MasiMaro 的技术博文

OLEDB 数据变更通知

除了之前介绍的接口,OLEDB还定义了其他一些支持回调的接口,可以异步操作OLEDB对象或者得到一些重要的事件通知,从而使应用程序有机会进行一些必要的处理。其中...

1063
来自专栏c#开发者

Msmq设计文档(赋源代码)

Msmq设计文档 文件状态: [√] 草稿 [ ] 正式发布 [ ] 正在修改 文件标识: ECI-MSMQ v01 当前版本: 0.5...

3518
来自专栏一“技”之长

iOS代码运行的磨刀石-预编译指令 原

所谓预编译,就是程序代码在编译之前,开发工具为我们预先做的一些工作。不要小瞧这些指令,没有它们,我们的代码可能寸步难行。

1002
来自专栏magicsoar

C++ socket网络爬虫(1)

C++写的socket网络爬虫,代码会在最后一次讲解中提供给大家,同时我也会在写的同时不断的对代码进行完善与修改 我首先向大家讲解如何将网页中的内容,文本,图片...

5415

扫码关注云+社区

领取腾讯云代金券