前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入解析java虚拟机技术又更新了,今天讲编译概述,调试方法

深入解析java虚拟机技术又更新了,今天讲编译概述,调试方法

作者头像
愿天堂没有BUG
发布2022-10-31 11:24:20
3250
发布2022-10-31 11:24:20
举报
文章被收录于专栏:愿天堂没有BUG(公众号同名)

调试方法

俗话说磨刀不误砍柴工,在研究即时编译器前了解调试方法和准备好调试工具是有必要的,了解了它们,可以从外部更直观地了解编译器的内部情况。

编译日志

简单观察编译行为可以使用-XX:+PrintCompilation参数实现,如代码清单7-7所示,它会输出所有编译过的方法:

代码清单7-7 -XX:+PrintCompilation输出

  • 时间戳 编译ID 属性 编译级别 方法名(方法大小) 退优化
  • 30631 3958 n 0 java.lang.Class::getDeclaringClass0 (native)
  • 30632 3959 b 3 MemNode::main (19 bytes)
  • 30634 3960 b 4 MemNode::main (19 bytes)
  • 30637 3959 3 MemNode::main (19 bytes) made not entrant
  • 30638 3961 % b 4 MemNode::main @ 2 (19 bytes)

时间戳表示编译完成的时间,与该时间相对的是JVM启动时间。属性字符有多种:%表示栈上替换(方法后面的@2表示发生栈上替换的字节码索引);s表示编译同步方法;!表示方法存在异常处理器;b表示阻塞模式下发生的编译;n表示封装native方法所发生的编译。编译级别即分层编译的等级。方法大小表示Java字节码大小而非编译产出的机器代码大小。

如果发生退优化,需要撤销之前编译过的方法,这时候尾部会标注made not entrant(方法取消进入),或made zombie(僵尸代码)。产生made not entrant的原因可能是编译器的乐观假设被打破,或者发生了分层编译。如代码清单7-7所示,MemNode::main方法首先经过3级的C1编译,后续又经过4级的C2编译,此时C1产生的机器代码就会被标注为取消进入,但是方法仍然保留在CodeCache,直到该方法不被虚拟机及服务线程使用,也不被其他方法调用时,再将方法标注为made zombie。

编译神谕

编译神谕是指-XX:CompileCommand=subcommand,<pattern>命令,通过它可以使用户控制虚拟机中即时编译器的行为。subcommand表示子命令,每个子命令都有特定的行为。

  • break:在编译器和生成的机器代码中打断点。
  • print:输出方法的汇编表示。
  • exclude:不编译和内联某个方法。
  • inline:总是内联某个方法。
  • dontinline:不内联某个方法。
  • compileonly:只编译。
  • log:用日志记录编译过程。

<pattern>用于指定方法,可以使用package/Class.method形式,也可以使用package.Class::method形式。方法名和类名可以使用星号(*)模糊匹配。

可视化工具

本节介绍3个主要的编译器的可视化工具。

1. c1visualizer

前文提到,中间表示是编译器的灵魂,为了了解编译器的工作机制,可以使用-XX:+PrintIR输出C1的HIR,使用-XX:+PrintIRWithLIR输出C1的LIR,但是这些选项是以文本形式输出的,而C1的中间表示是图IR,文本表示很难直观地表达它的结构,所以c1visualizer应运而生。

c1visualizer可以可视化地输出C1编译器的HIR和LIR,还能可视化LIR寄存器分配阶段的值的存活范围,如图7-7所示。

2. idealgraphvisualizer

idealgraphvisualizer是C2的中间表示的可视化工具,它可以帮助理解C2理想图的构造过程。

可以使用-XX:PrintIdealGraphLevel=<val>配合-XX:PrintIdealGraphFile=ideal.xml输出理想图的文本形式供idealgraphvisualizer分析。-XX:PrintIdealGraphLevel的可选值是0~4,值越大,输出的过程越详细,如图7-8所示。

idealgraphvisualizer还支持自定义过滤器以过滤理想图中的部分节点,同时支持Graal IR的可视化。

3. JITWatch

JITWatch可以方便地映射源码、字节码和JIT生成的机器代码,还可以支持可视化Code Cache、nmethod、编译时间线等,如图7-9所示。

本文给大家讲解的内容是深入解析java虚拟机:编译概述,调试方法

  1. 下篇文章给大家讲解的是深入解析java虚拟机:C1编译器,编译流程;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 愿天堂没有BUG 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 调试方法
  • 编译日志
  • 编译神谕
  • 可视化工具
  • 本文给大家讲解的内容是深入解析java虚拟机:编译概述,调试方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档