简介

想不想了解JVM最最底层的运行机制?想不想从本质上理解java代码的执行过程?想不想对你的代码进行进一步的优化和性能提升?

如果你的回答是yes。那么这篇文章非常适合你,因为本文将会站在离机器码最近的地方来观看JVM的运行原理:Assembly。

使用PrintAssembly

小师妹:F师兄,上次你给我介绍了java中的字节码,还有JIT中的LogCompilation和PrintCompilation的用法。虽然都非常有用,但是能不能更进一步,让我能以机器的眼光来看待JVM的执行?

小师妹,如果要探究JVM的运行本质,那就应该是机器码了。难道你要去读懂机器码?虽然我不是机器码的专家,但我猜那应该是个非常复杂的过程。

小师妹:F师兄,当然不是机器码,有没有比机器码更高级一点点的,我记得上大学的时候学过汇编语言,好像就是离机器码最近的语言了,JVM有没有相应的汇编语言呢?

必须有的,我们可以使用-XX:+PrintAssembly来将assembly打印出来。

但是打印assembly是有条件的,它就像一个高傲的姑娘,不是你想追求就能追求得上的。

我们使用下面的命令来查看系统对PrintAssembly的支持程度:

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

Java HotSpot(TM) 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(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

根据大家的运行环境的不同,得到的结果可能也是不同的,我是mac的系统,从上面的结果可以看到,在我的JDK8的环境中,显示缺少hsdis-amd64.dylib,所以PrintAssembly其实是禁用的。

小师妹:F师兄,那现在咋办呀?没有hsdis-amd64.dylib就用不了PrintAssembly了。

巴甫洛夫说过:问号是开启任何一门科学的钥匙。没有问题我们就创造问题,没有困难我们就制造困难,没有hsdis-amd64.dylib当然是安装咯。

具体怎么安装,大家自行探索吧,网上有很多安装的教程,这里就不一一介绍了。

这里想讨论一个很奇怪的事情,虽然在JDK8环境中,我们不能使用PrintAssembly,因为没有hsdis-amd64.dylib。但是当我切到最新的JDK14环境中,一切都很美好,PrintAssembly可以正常运行了。

如果我们在JDK14中同样运行上面的命令,我们会得到下面的结果:

上图说明JDK14中虽然可以正常运行但是结果却不是assembly code,说明在JDK14中还是需要安装hsdis-amd64.dylib才能够得到正确的assembly结果。

注意,JDK14也需要安装hsdis-amd64.dylib才能正确使用。

输出过滤

默认情况下,PrintAssembly输出的是所有的信息,但是JDK内部的代码我们不可能进行修改,一般来说并不关心他们的assembly输出,如果要指定我们自己编写的方法,可以使用CompileCommand:

CompileCommand=print,*MyClass.myMethod prints assembly for just one method
CompileCommand=option,*MyClass.myMethod,PrintOptoAssembly (debug build only) produces the old print command output
CompileCommand=option,*MyClass.myMethod,PrintNMethods produces method dumps

例如:

-XX:CompileCommand=print,com.flydean.PrintAssemblyUsage::testPrintAssembly

这样我们可以得到,只属于testPrintAssembly方法的输出:

总结

本文讲解了怎么使用PrintAssembly来输出JVM的汇编日志。我们会在后面继续讲解这些Assembly code到底有什么用。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-jit-printassembly/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

小师妹学JVM之:JIT中的PrintAssembly的更多相关文章

  1. 小师妹学JVM之:JIT中的PrintAssembly续集

    目录 简介 JDK8和JDK14中的PrintAssembly JDK8中使用Assembly JDK14中的Assembly 在JMH中使用Assembly 总结 简介 上篇文章和小师妹一起介绍了P ...

  2. 小师妹学JVM之:JIT中的LogCompilation

    目录 简介 LogCompilation简介 LogCompilation的使用 解析LogCompilation文件 总结 简介 我们知道在JVM中为了加快编译速度,引入了JIT即时编译的功能.那么 ...

  3. 小师妹学JVM之:JIT中的PrintCompilation

    目录 简介 PrintCompilation 分析PrintCompilation的结果 总结 简介 上篇文章我们讲到了JIT中的LogCompilation,将编译的日志都收集起来,存到日志文件里面 ...

  4. 小师妹学JVM之:JDK14中JVM的性能优化

    目录 简介 String压缩 分层编译(Tiered Compilation) Code Cache分层 新的JIT编译器Graal 前置编译 压缩对象指针 Zero-Based 压缩指针 Escap ...

  5. 小师妹学JVM之:深入理解JIT和编译优化-你看不懂系列

    目录 简介 JIT编译器 Tiered Compilation分层编译 OSR(On-Stack Replacement) Deoptimization 常见的编译优化举例 Inlining内联 Br ...

  6. 小师妹学JVM之:JVM中的Safepoints

    目录 简介 GC的垃圾回收器 分代回收器中的问题 safepoints safepoint一般用在什么地方 总结 简介 java程序员都听说过GC,大家也都知道GC的目的是扫描堆空间,然后将那些标记为 ...

  7. 小师妹学JVM之:cache line对代码性能的影响

    目录 简介 一个奇怪的现象 两个问题的答案 CPU cache line inc 和 add 总结 简介 读万卷书不如行万里路,讲了这么多assembly和JVM的原理与优化,今天我们来点不一样的实战 ...

  8. 小师妹学JVM之:JVM的架构和执行过程

    目录 简介 JVM是一种标准 java程序的执行顺序 JVM的架构 类加载系统 运行时数据区域 执行引擎 总结 简介 JVM也叫Java Virtual Machine,它是java程序运行的基础,负 ...

  9. 小师妹学JavaIO之:NIO中那些奇怪的Buffer

    目录 简介 Buffer的分类 Big Endian 和 Little Endian aligned内存对齐 总结 简介 妖魔鬼怪快快显形,今天F师兄帮助小师妹来斩妖除魔啦,什么BufferB,Buf ...

随机推荐

  1. Java实现 LeetCode 720 词典中最长的单词(字典树)

    720. 词典中最长的单词 给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答案中字典序最 ...

  2. Java实现 LeetCode 649 Dota2 参议院(暴力大法)

    649. Dota2 参议院 Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成.现在参议院希望对一个 Dota2 游戏里的改变作出决 ...

  3. Java实现 LeetCode 378 有序矩阵中第K小的元素

    378. 有序矩阵中第K小的元素 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ ...

  4. Java实现 蓝桥杯VIP 算法训练 输出米字形

    例如:n=3时,包含A,B,C:n=4时,包含A,B,C,D. 矩阵的正中间为n个字母中字典序最大的那个,从这个字母开始,沿着西北.正北.东北.正西.正东.西南.正南.东南八个方向各有一条由大写字母组 ...

  5. Java实现 LeetCode 275 H指数 II

    275. H指数 II 给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照升序排列.编写一个方法,计算出研究者的 h 指数. h 指数的定义: "h 代表"高 ...

  6. Java实现N*N矩阵旋转(360度)

    N*N矩阵旋转 Description 给你一个n*n的矩阵,你的任务是将它逆时针旋转角度d. [输入] 输入的第一个数为T,表示接下来有T组数据. 每组数据的格式如下: 第一行为两个整数n,d.1& ...

  7. Java实现 蓝桥杯VIP 算法提高 质数的后代

    算法提高 质数的后代 时间限制:1.0s 内存限制:256.0MB 问题描述 在上一季里,曾提到过质数的孤独,其实从另一个角度看,无情隔膜它们的合数全是质数的后代,因为合数可以由质数相乘结合而得. 如 ...

  8. Java实现蓝桥杯历届真题国王的遗产

    国王的遗产 题目描述 X国是个小国.国王K有6个儿子.在临终前,K国王立下遗嘱:国王的一批牛作为遗产要分给他的6个儿子. 其中,大儿子分1/4,二儿子1/5,三儿子1/6,- 直到小儿子分1/9. 牛 ...

  9. Nginx跨域及Https配置

    一.跨域 1. 什么是跨域? 跨域:指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制(指一个域下的文档或脚本试图去请求另一个域下的资源,这 ...

  10. 案例:DG主库未设置force logging导致备库坏块

    DG搭建时,官方文档手册有明确提到要设置数据库为force_logging,防止有nologging操作日志记录不全导致备库应用时出现问题. 虽然是老生常谈的安装规范,但现实中总会遇到不遵守规范的场景 ...