前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如果面试官让你分析类初始化阶段的死锁现象

如果面试官让你分析类初始化阶段的死锁现象

原创
作者头像
子牙老师
发布2022-04-25 10:39:46
4170
发布2022-04-25 10:39:46
举报
文章被收录于专栏:手写JVM专栏

哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…

准备写两篇文章透彻剖析下类的初始化阶段及初始化阶段的死锁问题:

  1. 类的初始化做什么
  2. JVM底层是如何实现类的初始化的
  3. 为什么会出现死锁问题
  4. 怎么解释死锁问题
  5. 如果证明你对死锁的判断是正确的
  6. 我是如何论证的(改Hotspot源码打日志)

会由浅入深,循序渐进展开。今天是第一篇,难度偏认知层面。读起来应该会很轻松愉快。

clinit

类初始化阶段做什么?其实很简单,执行clinit方法。这个方法哪里来的?你的Java代码中只要有静态属性或者是静态代码段,在编译的时候就会自动生成这个方法。

代码中有静态属性,如图

代码中有静态方法,如图

这段代码有两个地方需要注意下:1、静态代码块前可以写static,也可以不写;2、如果代码中有多个静态代码块,编译系统会合并成一个,合并后的代码顺序跟静态代码块的先后顺序保存一致。

死锁现象

国际惯例,上代码

这段代码运行起来的结果,如图

代码永远不会结束,其实在JVM层面,是发生了死锁。

检测死锁

一提到死锁,我们会马上想起JVM提供的工具:jconsole、visualvm…期待的结果是

但是很遗憾,目前没有工具能够检测出初始化阶段发生的死锁问题(我准备尝试写一个)。

为什么jconsole检测不到呢?看图

线程根据执行代码进入的空间来分,有这四种基本状态,目前能看得到的工具,或者是JVM开放的API,只能做到检测出thread_in_Java这种状态的线程死锁问题。

所以这个问题只能通过阅读Hotspot源码找答案。所以可以推测出面试官问你这个问题,就是看你有没有这个能力,或者是这个习惯,通过阅读Hotspot源码找答案。

初始化流程

类的初始化阶段,对应Hotspot源码:InstanceKlass::initialize_impl。考虑到很多小伙伴不想看C++代码,我用伪代码把意思表达到

讲两个预备知识:

  1. 看这段代码的时候要区别正在执行初始化的线程及其他线程。假设正在执行初始化的线程为T1,又进来一个线程T2执行初始化
  2. Hotspot源码中此处有两个状态对理解代码至关重要:being_initialized(正在执行初始化)、fully_initialized(完成初始化)

问题的答案已经很清晰了:

  1. 第一个线程执行new指令,触发加载类A,然后执行A的初始化方法clinit,clinit方法中又执行到new指令,触发加载类B,并执行类B的初始化方法clinit
  2. 第二个线程触发加载类B,在类B的clinit方法中又触发加载类A
  3. 死锁的原因就是线程一跟线程二都进入了wait,也就是初始化流程的Step 2
  4. 其实这个问题存在时间差,如果某个线程跑得足够快,完成了初始化,死锁就不会发生。所以如果你的程序出现有时候卡着不动,有时候又是正常的,不妨大胆猜测有可能是发生了初始化阶段死锁。正常来讲,出现死锁的频率更高,我测试了很多次,理想情况发生的次数还是很少很少的

然,目前得出的答案是从理论层面分析出来的,那事实是不是如此呢?如何证明呢?下篇文章分享。

题外话

子牙手写JVM小班四期正在招生。四期新增了字节码增强+Agent,学完你就可以做JVM相关的工作,如二开arthas,自研类hsdb调试器、自研实现热更新热部署零侵入日志等黑科技…

四期完整课程包含七大专题+一个增值专题,约50多个课时。完整学完你就可以:1、用Java写一个Java虚拟机,从而深入理解运行系统的底层细节;2、有能力自行研究Hotspot源码及其他用C语言、C++写的中间件源码;3、能够用C语言、C++写任何你感兴趣的基础算法如:内存池、垃圾回收算法、主从同步算法、执行引擎、存储引擎;4、就有底子跟着我学习下半年准备开的操作系统内核班……

这套课程,横跨多个计算机学科,但只是一个学科的价格。这套课程,JVM专家、功力深厚、经验丰富的子牙老师亲授,跟我学习不踩坑,全网唯一教授虚拟机的课程…

感兴趣小伙伴可以加班班微信咨询(jvm-anan),真诚招生,无任何套路。课程试看,问题真诚解答,全部了解清楚再上车。一二三期共500多VIP加入,无一人退费,好评不断

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • clinit
  • 死锁现象
  • 检测死锁
  • 初始化流程
  • 题外话
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档