Java字节码反编译成汇编插件


Java 字节码反编译成汇编插件


环境:
(1)windows10环境
(2)jdk “1.8.0_261” 64位
(3)Java HotSpot™ 64-Bit Server VM (build 25.261-b12, mixed mode)


一、报错详情

报错提示(如下图):Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
在这里插入图片描述


也可使用cmd测试重现:java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version
在这里插入图片描述


二、解决方法

1、下载并配置环境

(1)确保已安装jdk1.8

(2)安装hsdis-amd64.dylib 和 hsdis-amd64.dll

①下载hsdis-amd64.dylib,网盘下载地址(验证码:hhg5)

将下载好的hsdis-amd64.dylib文件放置在JDK路径下的\jre\lib目录下。

②下载hsdis-amd64.dll,网盘下载地址(验证码:mdpg)

将下载好的hsdis-amd64.dll文件放置在JDK路径下\jre\bin\server目录下。


(2)在cmd中使用命令java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version 验证是否配置成功。如果出现如下所示则说明配置成功。
Java字节码反编译成汇编插件_第1张图片


2、IDEA软件中测试

测试类:

package com.company.thread;

/**
 * @author: zhangxh
 * @date: 2023/03/29 08:39
 * @Desc: 可见性问题测试
 *
 * 运行方法:
 * (1)cd 到当前类目录
 * (2)cdm执行命令:java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp
 */
public class VisibilityTest {

    private boolean flag = true;

    public void refresh() {
        flag = false;
        System.out.println(Thread.currentThread().getName() + "修改flag");
    }

    public void load() {
        System.out.println(Thread.currentThread().getName() + "开始执行.....");
        int i = 0;
        while (flag) {
            i++;
            //TODO  业务逻辑
        }
        System.out.println(Thread.currentThread().getName() + "跳出循环: i=" + i);
    }

    public static void main(String[] args) throws InterruptedException {
        VisibilityTest test = new VisibilityTest();

        // 线程threadA模拟数据加载场景
        Thread threadA = new Thread(() -> test.load(), "threadA");
        threadA.start();

        // 让threadA执行一会儿
        Thread.sleep(1000);
        // 线程threadB通过flag控制threadA的执行时间
        Thread threadB = new Thread(() -> test.refresh(), "threadB");
        threadB.start();

        System.out.println("sss");

    }

    public static void shortWait(long interval) {
        long start = System.nanoTime();
        long end;
        do {
            end = System.nanoTime();
        } while (start + interval >= end);
    }

}

使用命令java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=print,*VisibilityTest.main
Java字节码反编译成汇编插件_第2张图片

注: 使用CompileCommand命令反编译指定代码方法

CompileCommand 参数:

作用:用来定制编译需求,可以指定某个方法不做 JIT 编译,也可以只编译指定的方法等等。

语法:

-XX:CompileCommand=command,method[,option]

其中的 command 有下面这些选项:

  • exclude,跳过编译指定的方法
  • compileonly,只编译指定的方法
  • inline/dontinline,设置是否内联指定方法
  • print,打印生成的汇编代码
  • break,JVM以debug模式运行时,在方法编译开始处设置断点
  • quiet,不打印在此命令之后、通过-XX:CompileCommand指定的编译选项
  • log,记录指定方法的编译日志,若未指定,则记录所有方法的编译日志
  • 其他命令,option,help

上面的测试命令: -XX:CompileCommand=print,*VisibilityTest.main,仅反编译VisibilityTest的main方法。

你可能感兴趣的:(软件使用技巧,java,汇编,jvm)