JIT中的PrintAssembly续集

简介
上篇文章和小师妹一起介绍了PrintAssembly和PrintAssembly在命令行的使用,今天本文将会更进一步讲解如何在JDK8和JDK14中分别使用PrintAssembly,并在实际的例子中对其进行进一步的深入理解。

JDK8和JDK14中的PrintAssembly
小师妹:F师兄,上次你介绍的PrintAssembly的自测命令,怎么在JDK14中不好用呢?

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version
有什么不好用的,命令不是正常打出来了吗?

小师妹:F师兄,你看下我运行的结果,机器码下面展示的怎么是448b 5608这样的数字呀,不应该是assembly language吗?

嗯…小师妹的话让我陷入了深深的思考,究竟是什么导致了这样的反常的结果呢?是道德的沦丧还是人性的扭曲?

于是我翻遍了baidu,哦,不对是google,还是没有找到结果。

难点是JDK14有bug?还是JDK14已经使用了另外的Assembly的实现?

有问题就解决问题,我们先从JDK8开始,来探索一下最原始的PrintAssembly的使用。

更多精彩内容且看:

区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程
JDK8中使用Assembly
在JDK8中如果我们运行Assembly的测试命令,可以得到下面的结果:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version

Java HotSpot™ 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
Could not load hsdis-amd64.dylib; library not loadable; PrintAssembly is disabled
java version “1.8.0_171”
Java™ SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot™ 64-Bit Server VM (build 25.171-b11, mixed mode)
这个故事告诉我们,虽然PrintAssembly开关打开了,但是系统不支持,缺少了hsdis-amd64.dylib文件。

这个hsdis是一个反汇编的工具,我们需要hsdis的支持才能在JDK8中使用Assembly。

我是mac系统,下面是在mac系统怎么安装hsdis:

hg clone http://hg.openjdk.java.net/jdk8u/jdk8u

cd jdk8u/hotspot/src/share/tools/hsdis/

wget http://ftp.heanet.ie/mirrors/ftp.gnu.org/gnu/binutils/binutils-2.30.tar.gz

tar -xzf binutils-2.30.tar.gz

make BINUTILS=binutils-2.30 ARCH=amd64

#java8
sudo cp build/macosx-amd64/hsdis-amd64.dylib /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/server/

#java9 onwards
sudo cp build/macosx-amd64/hsdis-amd64.dylib /Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home/lib/server/
如果你是linux或者windows系统,请自行探索hsdis的安装方法。

按照步骤先把java8的hsdis-amd64.dylib安装好。

然后再次运行测试命令:

完美,汇编语言出现了。

JDK14中的Assembly
然后我想到,如果把这个dylib文件拷贝到JDK14相应的目录下面,运行一次会怎么样呢?

大家注意,JDK9之后,使用了模块化,所以之前的目录结构发生了比较大的变化,大家参考上面我列出的地址。

再次运行测试代码:

大家看到,Assembly又出现了,真的是让我热内盈亏。

其实最开始的时候,我发现JDK14中Assembly没能正常显示的时候,我也有想过拷贝一个hsdis-amd64.dylib过来试试,但是一看还需要下载JDK的代码,重新编译,就打起了退堂鼓。

吃一堑,长一智,下次遇到问题千万不能走捷径。抄近路害死人呀!

在JMH中使用Assembly
Assembly主要是为了进行代码调优或者理解JVM的运行原理来使用的。

这里我们举一个在JMH中使用Assembly的例子:

@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(value = 1,
jvmArgsPrepend = {
“-XX:+UnlockDiagnosticVMOptions”,
“-XX:CompileCommand=print,com.flydean.PrintAssemblyUsage::testPrintAssembly”
}
)
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class PrintAssemblyUsage {

int x;
@Benchmark
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
public void testPrintAssembly() {
    for (int c = 0; c < 1000; c++) {
        synchronized (this) {
            x += 0xFF;
        }
    }
}
public static void main(String[] args) throws RunnerException {
    Options opt = new OptionsBuilder()
            .include(PrintAssemblyUsage.class.getSimpleName())
            .build();

    new Runner(opt).run();
}

}
上面的例子中,我们使用了-XX:CompileCommand指定要打印的方法,而不是输出所有的Assembly,方便我们查看和分析结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值