HotSpot VM中的准确式GC、OopMap、Safepoint、抢先式中断、主动式中断、Safe Region和RememberedSet

本文主要是介绍HotSpot VM中的准确式GC、OopMap、Safepoint、抢先式中断、主动式中断、Safe Region和RememberedSet,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相关文章

  • Java运行时数据区域
  • Java对象的创建和内存布局
  • 最全JVM的参数总结

文章目录

          • 可达性分析
          • 保守式GC
          • 准确式GC与OopMap
          • Safepoint、抢先式中断、主动式中断
          • Safe Region
          • RememberedSet

首先,我们要了解一下这个主题的背景,为什么会出现这一系列名词。这些名词都是在如何提高GC效率的问题上提出的,具体讲,是如何提高GC Roots扫描效率的问题。

可达性分析

我们知道要判断一个对象是否可以被回收,是通过判断这个对象与GC Roots之间是否存在引用链,这个过程叫做可达性分析。而这个过程中,业务线程是需要停止的,不然在遍历时,引用发生变化,那么分析到的结果就是不准确的。也就是说这个过程需要“Stop the world”。为了提高效率,我们需要这个过程尽可能地快,以减少系统停顿时间。

怎么提高这部分的效率呢?首先在遍历GC Roots的速度能否提高?

保守式GC

在JDK1.0时,Sun公司发布JVM,称为Sun Classic VM,这款虚拟机只支持纯解释器方式来执行java代码,如果想使用JIT编译期就必须进行外挂,但是外挂后解释器就不工作了,总之两者不兼容。不止于此这款JVM,遍历GC Roots时,扫描内存中全局变量和栈上的本地变量表时,并不知道这个位置存的是基本数据类型还是对象引用,需要额外判断,效率很低。Classic VM其使用的是基于句柄的访问方式,每次定位都需要两次定位,其速度就可想而知了,这种方式称为“保守式内存管理”和“保守式GC”。

准确式GC与OopMap

为了解决上面的问题,Sun团队发布了一款叫做Exact VM的虚拟机。它的最大特点是“准确式内存管理”,即虚拟机知道内存中某个位置存储的数据是什么类型,在GC时,只需遍历引用类型即可,并且采用直接引用,其效率提高了一个level。其用来维护哪些地方存有引用的数据结构就叫做“OopMap”。后来HotSpot VM继承了这一技术。

Safepoint、抢先式中断、主动式中断

OopMap存储的是哪些地方存有引用。但是维护这个数据结构太难了,系统在多线程地跑,对象千千万万,时时刻刻引用关系都在发生变化,不管是采用频繁地修改OopMap的值,还没每执行一条指令(只有执行指令,引用关系才会改变)都创建一个OopMap都是不可取的。那么怎么办呢?

HotSpot提出只在某些特殊的位置记录引用信息,这些特殊的位置就被称为“Safepoint”。程序也只会在这些Safepoint才会停下来。GC发生时如何让所有线程都跑到Safepoint停下来呢?有两种方案:抢先式中断和主动式中断。抢先式中断:GC时,把所有线程都中断,如果线程没达到Safepoint,就再启动线程跑到Safepoint后停下来。这种方式频繁地线程切换,性能差,已经没有虚拟机采用了。另一种,主动式中断:当发生GC时,设置一个标记,所有线程在到达Safepoint时判断这个标记,如果中断标记为真就自己中断挂起。

Safe Region

如果线程已经停止了,那要怎么到达Safepoint呢?对于这个问题就需要安全区域(Safe Region)解決。Safe Region指一段代码判断之中,引用关系不会发生变化。在这个区域中发生GC都是安全的。线程停止都会进入到Safe Region中,当线程回复执行,也就是从Safe Region离开时,会先检查系统是否正在GC,是的话会等到GC完成后离开Safe Region。

RememberedSet

我们知道新生代GC会非常频繁,当只想收集新生代,不想收集老年代时,没有必要对位于老年代的 GC Roots 做全面的可达性分析。但问题是可能存在位于老年代的某些GC Roots引用了新生代的某个对象,这时这个对象是不能清除的。那么怎么办呢?
我们可以用一个结构维护老年代引用新生代的情况,这个结构就是“RememberedSet”。

我们知道, G1 收集器使用的是化整为零的思想,把一块大的内存划分成很多个域( Region )。但问题是,难免有一个 Region 中的对象引用另一个 Region 中对象的情况。为了达到可以以 Region 为单位进行垃圾回收的目的, G1 收集器也使用了 RememberedSet 这种技术,在各个 Region 上记录自家的对象被外面对象引用的情况。

欢迎关注公众号:
在这里插入图片描述

这篇关于HotSpot VM中的准确式GC、OopMap、Safepoint、抢先式中断、主动式中断、Safe Region和RememberedSet的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/191782

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

HotSpot虚拟机的经典垃圾收集器

读《深入理解Java虚拟机》第三版笔记。 关系 Serial、ParNew、Parallel Scavenge、Parallel Old、Serial Old(MSC)、Concurrent Mark Sweep (CMS)、Garbage First(G1)收集器。 如图: 1、Serial 和 Serial Old 收集器 2、ParNew 收集器 3、Parallel Sc

FreeRTOS学习笔记(四)Freertos的中断管理及临界保护

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Cortex-M 中断管理1.1 中断优先级分组1.2 相关寄存器1.3 相关宏定义1.4 FreeRTOS 开关中断 二、临界段及其保护2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )2.2 taskENTER_CRITICAL_FROM_ISR( )

Cortex-A7:ARM官方推荐的嵌套中断实现机制

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf ARM体系结构与编程第2版 1 前言 Cortex-M系列内核MCU中断硬件原生支持嵌套中断,开发者不需要为了实现嵌套中断而进行额外的工作。但在Cortex-A7中,硬件原生是不支持嵌套中断的,这从Cortex-A7中断向量表中仅为外部中断设置了一个中断向量可以看出。本文介绍ARM官方推荐使用的嵌套中断实现机

每天一道面试题(2):fail-safe 机制与 fail-fast 机制分别有什么作用?

当谈论Java集合的 fail-fast 和 fail-safe 机制时,涉及的是在集合被并发修改时的行为和处理方式。这些机制对保证程序的正确性和稳定性非常重要,尤其是在多线程环境中。 1. Fail-Fast 机制 定义: Fail-fast 机制的核心是在检测到集合在遍历过程中被修改时,立即抛出 ConcurrentModificationException 异常,从而中断迭代操作。这种

解决PHP Warning: strftime(): It is not safe to rely on the system's timezone set

当运行一些程序时,在httpd日志中会有如下警告日志: PHP Warning:  strftime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set(

外部中断的边缘触发和电平触发

MCS-51单片机中的边缘触发是指当输入引脚电平由高到低发生跳变时,才引起中断。而电平触发是指只要外部引脚为低电平就引起中断。         在电平触发方式下,当外部引脚的低电平在中断服务返回前没有被拉高时(即撤除中断请求状态),会引起反复的不需要的中断,造成程序执行的错误。这类中断方式下,需要在中断服务程序中设置指令,清除外部中断的低电平状态,使之变为高电平。

LLVM IR指令VM混淆分析

未混淆编译  编写一个最简单的测试代码,对 test_add函数用于对两个数相加: int __attribute((__annotate__("vm"))) test_add(int a, int b) {int c = a + b;return c;}int main(void) {int c = test_add(1, 2);return c;} 编译成中间代码:  未加

【Java编程思想】线程的基本协作机制 与 线程的中断

wait/notify Java在Object类中定义了一些线程协作的基本方法,wait和notify public final void wait() throws InterruptedException;public final native void wait(long timeout) throws InterruptedException; 一个带时间参数,单位是毫秒,表示最