0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

JVM入门之关于GC的扩展知识2

jf_78858299 来源:北洋洋洋 作者:北洋 2023-02-10 11:35 次阅读

5.一个"小Bug":线程如果不执行呢?

上面说到过现在虚拟机采用的几乎都是主动式中断来中断线程,而其实现又是通过 「线程执行过程中不断轮询标志位」 产生自陷异常信号在异常处理表中进行中断线程,

大家有没有发现有个小bug:如果我轮询的操作一直得不到执行呢?这个时候我又该如何让虚拟机进入垃圾回收状态。

其实不一定都需要进行中断线程来保证,回想下STW是为什么:因为如果这个时候用户线程还在执行的话内存中的引用关系可能会发生变化,所以才需要进行STW。如果一个线程没有得到CPU时间片执行(java中的线程对应于操作系统的线程,对应关系也可以找笔者之前的关于SignCatcher对线程的理解进行查阅),但是我可以确保其中一部分代码区域是不会改变内存引用关系的,这样也可以不用管这些线程。

引入Safe Region(安全区域)解决

“安全区域:这部分代码不会使内存中的引用关系发生变化”,因此只要进入了安全区域,虚拟机就不会管这些线程。当线程离开安全区域后,如果这个时候引用链还没有形成(也就是通过GC Roots遍历堆内存)那么是不能离开的,一直等待直至引用链形成(或者完成了垃圾回收器需要暂停用户线程的阶段)收到信号为止。

6. GC Roots会随着运行时间变长而增加吗?

基础知识介绍

根据堆中的不同区域(分代设计)和回收内存空间来判定分为不同的GC名称:局部回收:Minor GC,MajorGC,..... 整个内存回收:Full GC

如果存在“跨代引用”(最典型的比如老年代对象引用年轻代对象),比如发生Minor GC时,只遍历普通的GC Roots对象其实结果并不准确( 「某些对象虽然本身不属于GC Roots但是随着经历的GC次数变多成为老年代对象」 ),如果这个时候将这个引用的年轻代对象标记为垃圾清除后,老年代中的对象就会有问题,所以引用链形成的过程中还需要 「遍历整个老年代来保证结果准确」

CPU的缓存行技术及伪共享解决方案

!

记忆集

跨域可以理解为跨内存访问或者访问其他分代里面的内存

上面遍历整个老年代这个过程听起来就很耗时哈哈,事实也确实如此。那么我们可以引入这么一个概念:如果你引用了其他内存里面的对象那么我把你存放到其他内存里面的一个数据结构里面,之后其他内存回收的时候只需要把之前添加到数据结构里面的对象加入到GC Roots中即可。

我们优化一下: 「每个不同的分代中都存着一个数组」 ,这个数组中对堆内存进行一个映射, 我数组中的每一小块对应的元素是分代中固定大小的内存(比如我第一个数组下标表示我引用的是0到100,第二个数组下标表示引用的是100-200以此类推)。 「当我第一个数组下标对应内存跨域引用了其他分代中的内存,我将把第一个数组下标对应的内存的元素值标识为1代表脏(Dirty)」 ,没有则为0。当垃圾回收时,我就知道哪部分内存是跨代引用并将他们加入到GC Roots进行扫描(将数组中元素为1对应的内存对象加入GC Roots中)。

根据我映射的内存大小精度又可以进行细分:1.字长精度:只记录一个机器字长(处理器的寻址位数)该字包含跨代指针

2.对象精度:记录一个对象(对象字段中含有跨代指针)

3.卡精度:记录一块内存区域(该区域有对象包含跨代指针)

最常用的精度

采用“卡精度”的记忆集是通过“卡表”这个数据结构来实现的。

使用精度为卡,这个记忆集的实现方式也被称为 「卡表」 ,卡表中其实是字节数组结构,每个数组中的元素都对应一部分指定大小内存块,这部分内存被称作 「卡页」 ,当卡页中的内存块中引用了其他的内存块中的一个或多个对象,就会将卡页中的元素值变为一。变为一的就是脏数据,收集时讲这部分内存加入到gc roots中。也就是这样的:

可能出现的问题

一, 「何时进行更新卡表?」 先看我这张图哈哈,字不好看,但是大致意思是差不多的。

我在写后屏障中进行更新卡表就可以保证我的卡表记录是正确的。

二, 「“伪共享引起的问题”」 上面刚刚讲过CPU的缓存行技术,简单来说就是如果两个线程中两个独立的变量在同一块缓存行中,那么不管是哪个线程修改,另外一个线程都需要重新从主存中读取,而设置缓存行就是为了加快读取效率,所以这样势必会降低效率。

想想刚刚我们记忆集处理方式,如果卡页对应的内存中发生跨代引用,那么就会对卡表进行更新;上面说的“伪共享”也会在这里出现而且影响性能,比如: 「一个缓存行六十四个字节;一个卡表中的一个元素是一个字节,每个元素对应的一个卡页存储的是512字节,也就是一个卡表中64个元素在一个缓存行,而这64个元素对应的总卡页内存为32KB(64 X 512字节)」 ,如果两个线程中的变量分配到了这部分内存中,之后变量发生跨代引用更新卡表元素时就会导致另一个线程的缓存行失效而从主存中去拿。所以应该减少更新卡表这个操作,如果已经更新过脏数据了就不需要进行更新卡表了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3615

    浏览量

    93721
  • GC
    GC
    +关注

    关注

    0

    文章

    9

    浏览量

    17083
  • JVM
    JVM
    +关注

    关注

    0

    文章

    158

    浏览量

    12223
收藏 人收藏

    评论

    相关推荐

    电子技术入门维修基础知识

    电子技术入门维修基础知识
    发表于 08-17 20:03

    请问单例对象会被jvmgc时回收吗?

    单例对象会被jvmgc时回收吗?
    发表于 11-09 07:02

    JVM知识点汇总,不看肯定后悔

    JVM知识点汇总,不看肯定后悔
    发表于 11-30 06:13

    看看基于JDK中自带JVM工具的用法

    查询很多参数的默认值;该命令还可以在运行时动态调整部分参数,只是很少被使用;3、jstat命令jstat :以指定的频率输出JVM的监控指标,下述命令输出内存占用和GC相关信息,每隔3秒输出一次,连续
    发表于 11-16 15:30

    初学者AVR软件入门基础知识2

    初学者AVR软件入门基础知识2
    的头像 发表于 07-04 09:50 2667次阅读

    Java:JVM虚拟机的入门知识

    Java开发现在面试越来越难了,进大厂必备的JVM、多线程高并发这都是最基础的知识了,今天我们一起来学习Java虚拟机入门
    的头像 发表于 07-01 11:43 2314次阅读
    Java:<b class='flag-5'>JVM</b>虚拟机的<b class='flag-5'>入门</b><b class='flag-5'>知识</b>

    如何解决JVM解释器导致应用崩溃的bug

    bug 导致在弱内存模型的平台上 Crash。 在分析过程中,涉及到非常多的 JVM 内部知识,比如对象头、GC 复制算法操作、CAS 操作、字节码执行、内存序等,希望对读者有所帮助。本文介绍了一般分析
    的头像 发表于 08-27 09:58 2436次阅读
    如何解决<b class='flag-5'>JVM</b>解释器导致应用崩溃的bug

    关于JVM的调优知识

    最近很多小伙伴跟我说,自己学了不少JVM的调优知识,但是在实际工作中却不知道何时对JVM进行调优。今天,我就为大家介绍几种JVM调优的场景。
    的头像 发表于 09-14 14:54 833次阅读

    一次JVM GC长暂停的排查过程

    在高并发下,Java 程序的 GC 问题属于很典型的一类问题,带来的影响往往会被进一步放大。不管是「GC 频率过快」还是「GC 耗时太长」,由于 GC 期间都存在 Stop The W
    的头像 发表于 01-17 10:08 609次阅读

    JVM入门历代垃圾回收器 2

    很多人经常把这两个搞混,当然笔者刚开始的时候也是傻傻分不清楚。其实只要记住并行说的是GC 线程之间的关系,而并发说的是GC和用户线程之间的关系
    的头像 发表于 02-10 11:29 595次阅读
    <b class='flag-5'>JVM</b><b class='flag-5'>入门</b><b class='flag-5'>之</b>历代垃圾回收器 <b class='flag-5'>2</b>

    JVM入门关于GC扩展知识1

    本章主要是对上一篇文章讲的垃圾回收机制的扩展,垃圾回收其实本身是有很多可以优化的点的,本章就进行对这些优化点进行介绍。
    的头像 发表于 02-10 11:35 556次阅读
    <b class='flag-5'>JVM</b><b class='flag-5'>入门</b><b class='flag-5'>之</b><b class='flag-5'>关于</b><b class='flag-5'>GC</b>的<b class='flag-5'>扩展</b><b class='flag-5'>知识</b>1

    JVM入门垃圾回收算法

    根据如何判定对象是垃圾,垃圾回收算法分为两类:1、 「引用计数式垃圾收集」 (判定垃圾是通过引用计数器)别名:直接垃圾收集 2、 「追踪式垃圾收集」 (判定垃圾是通过GC Roots)别名:间接垃圾收集
    的头像 发表于 02-10 11:40 818次阅读
    <b class='flag-5'>JVM</b><b class='flag-5'>入门</b><b class='flag-5'>之</b>垃圾回收算法

    JVM的一些重要参数

    ,默认GC 是G1 GC算法。Java 17 默认也是G1 GC,其中个别版本会有点差异。 下面是常用GC算法使用命令。 GC Algor
    的头像 发表于 09-25 15:56 469次阅读

    JVM知识体系剖析

    从源码到运行、类加载,再到内存分配和垃圾回收,以及JVM调优的技巧与实战。 理论-实战-面试三结合,带大家剖析整个JVM知识体系,一站解决JVM问题。 1、Oracle Java SE
    的头像 发表于 10-10 11:37 427次阅读
    <b class='flag-5'>JVM</b><b class='flag-5'>知识</b>体系剖析

    从原理聊JVM(一):染色标记和垃圾回收算法

    更好地优化自己的代码,并解决一些潜在的性能问题。 本文及后续文章将从原理聊起,对JVM的内存分配、GC、编译等知识进行分析和总结。 1 JVM运行时内存划分 1.1 运行时数据区域 
    的头像 发表于 08-20 15:25 239次阅读
    从原理聊<b class='flag-5'>JVM</b>(一):染色标记和垃圾回收算法