对比Java源码、字节、汇编

参考:https://www.cnblogs.com/thisiswhy/p/14750596.html

JVM参数说明

输出JIT日志

     -client
     -XX:+UnlockDiagnosticVMOptions
     -XX:+PrintAssembly
     -XX:+LogCompilation
     -XX:LogFile=jit01.log

禁用OSR优化

     -XX:-UseOnStackReplacement

参考:https://juejin.cn/post/6844904038580879367

-XX:+UnlockDiagnosticVMOptions:解锁用于 JVM 诊断的选项。
-XX:+PrintAssembly:配合反汇编插件(例如 hsdis-amd64.dylib)可以打印出字节码和本地方法的汇编码;必须和 -XX:+UnlockDiagnosticVMOptions 一起使用。
-Xcomp:在第一次调用时强制编译方法。默认情况下,无论是 -client 模式还是 -server 模式,都需要执行一定次数解释方法的调用才会触发方法的编译。(如果需要 JIT 日志,则不指定该参数)
-XX:CompileCommand=compileonly,*ClassName.methodName:只编译类名为 ClassName 中的 methodName 方法,支持使用 * 作为通配符。可以多次指定 -XX:CompileCommand 添加多条命令。(建议只指定需要的方法,否则将会产生大量的无关日志)
-XX:+LogCompilation:允许将编译活动记录到当前工作目录中名为 hotspot.log 的文件中。可以通过 -XX:LogFile 指定文件的路径和名字。
-XX:LogFile=path:指定日志的路径和文件名。例如:-XX:LogFile=/var/log/hotspot.log

环境说明

JDK:1.8
OS:windows 10

运行一下代码发现是死循环

package com.xh.d0511;

public class Test01 {
    static private boolean flag = false;
    static private int iflag = 0;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                    flag = true;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        while (!flag) {
            new A(1);
        }
        System.out.println(flag);
    }

    static class A {
        private int age;
        private int b;

        public A(int age) {
            this.age = age;
        }
    }
}

如果A中改为:
private final int age;

则正常结束。

这个现象在JDK14中不存在,都是死循环

所以就是要看看加了final的汇编指令和没有加在JDK1.8中有什么不一样

jitwatch比较汇编代码

https://github.com/AdoptOpenJDK/jitwatch

注意:需要在jdk的server下加入hiddis.dll

这玩意儿太不好用了

原文地址:https://www.cnblogs.com/lanqie/p/14758507.html