通过JITWatch查看汇编代码,观测jdk17改动对代码的影响


前言

我们可以使用JITWatch来观测线上代码实际运行逻辑,来进行一些问题分析和学习参考。虽然线上运行的是机器指令,但是为了方便阅读和理解,JITWatch执行的都是汇编代码,是ARM指令集的汇编代码,不过咱们可以借助chat-gpt或者豆包等大模型帮忙解读


一、JITWatch是什么?

JITWatch是一个反编译查看工具,顾名思义,可以用来Watch JIT代码,帮助我们分析代码实际运行过程中的逻辑。

二、问题描述

1.公司线上问题

某个团队发现线上读TP999,总会时不时地出现一次抖动,通过公司的技术大盘观测,同一时间cpu.busy也会突然抖动一下。然后他们结合JFR,在线上服务再次复现问题时,观测到活跃线程居然是“C2 Compiler Thread”,咱们javaer看到这个,都会有点眼熟吧,毕竟各种八股文都背过。进一步观测发现,此时C2 Compiler Thread都是在进行分支预测(profile_predicate)失败导致的“逆优化,再编译”。

1.1 分支预测

其实这个问题,我也是学习到了,本来以为分支预测只会发生在操作系统调度指令流水线期间,如果预测失败,会清空指令流水线,重新加载另外一个分支。没想到C2编译器啊,你这个浓眉大眼的,居然在编译层面就做了一些分支预测的工作。

1.2 逆优化,再编译

咱们都知道C2的作用,就是为了做JIT,将字节码编译为机器码,然后运行。那逆优化,再编译,其实就是指编译的机器码出了问题,需要退化为字节码,再进行解释执行。
本来是操作系统可直接执行的机器指令,逆优化变为了Java的字节码指令,jvm的解释器需要借助CPU再次解释字节码指令为机器指令,然后CPU重新执行机器指令。也就是指令的生命周期那套。

2. 模拟问题(复现)

2.1 模拟环境

系统:macOS
Java版本:Java17
HotSpot17:直接下载就行
openjdk17:因为必须要修改源码,所以使用openjdk来做
JITWatch
:jitwatch-ui-1.4.7-shaded-mac.jar

下载地址:https://github.com/AdoptOpenJDK/jitwatch/releases

2.2 准备工作

  1. 下载openjdk17:https://github.com/openjdk/jdk17u
  2. 修改分支预测代码逻辑:src/hotspot/share/opto/parse2.cpp:1291,将branch_prediction改为以下代码
//-----------------------------branch_prediction-------------------------------
float Parse::branch_prediction(float& cnt,
                               BoolTest::mask btest,
                               int target_bci,
                               Node* test) {
    return PROB_FAIR;
}
  1. 编译openjdk17
    编译好的jdk的java_home:jdk17u/build/macosx-x86_64-server-slowdebug/images/jdk
  2. 下载JITWatch

2.3 复现步骤

  1. Java代码,咱们这段代码的某段逻辑一定不会走进去,也就是return 0x666
public class FirstTest {
   
   

    private static int test(int num) {
   
   
        if (num > 0) {
   
   
            return 0x123;
        }
        return 0x666;
    }

    public static void main(String[] args) {
   
   
        long res = 0;
        for (int j = 0; j < 100_000_000_0L; j++) {
   
   
            res += test(j);
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值