22 | 深入JVM即时编译器JIT,优化Java编译
刘超
该思维导图由 AI 生成,仅供参考
你好,我是刘超。
说到编译,我猜你一定会想到 .java 文件被编译成 .class 文件的过程,这个编译我们一般称为前端编译。Java 的编译和运行过程非常复杂,除了前端编译,还有运行时编译。由于机器无法直接运行 Java 生成的字节码,所以在运行时,JIT 或解释器会将字节码转换成机器码,这个过程就叫运行时编译。
类文件在运行时被进一步编译,它们可以变成高度优化的机器代码,由于 C/C++ 编译器的所有优化都是在编译期间完成的,运行期间的性能监控仅作为基础的优化措施则无法进行,例如,调用频率预测、分支频率预测、裁剪未被选择的分支等,而 Java 在运行时的再次编译,就可以进行基础的优化措施。因此,JIT 编译器可以说是 JVM 中运行时编译最重要的部分之一。
然而许多 Java 开发人员对 JIT 编译器的了解并不多,不深挖其工作原理,也不深究如何检测应用程序的即时编译情况,线上发生问题后很难做到从容应对。今天我们就来学习运行时编译如何实现对 Java 代码的优化。
类编译加载执行过程
在这之前,我们先了解下 Java 从编译到运行的整个过程,为后面的学习打下基础。请看下图:
类编译
在编写好代码之后,我们需要将 .java 文件编译成 .class 文件,才能在虚拟机上正常运行代码。文件的编译通常是由 JDK 中自带的 Javac 工具完成,一个简单的 .java 文件,我们可以通过 javac 命令来生成 .class 文件。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
JVM即时编译器JIT对Java代码进行优化是Java运行时编译的重要组成部分。文章详细介绍了Java代码从编译到运行的整个过程,包括类加载、连接和初始化,以及即时编译器的优化过程。在HotSpot虚拟机中,内置了两个JIT,分别为C1编译器和C2编译器,并介绍了分层编译的优势。热点探测是JIT优化的条件,基于计数器的热点探测会触发JIT编译。文章还涉及了方法内联和逃逸分析等优化手段,以及在Java8和Java9中的编译器变化。总的来说,本文详实介绍了JVM即时编译器JIT对Java代码优化的过程和原理,对于理解Java代码的运行和性能优化具有重要参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 性能调优实战》,新⼈⾸单¥59
《Java 性能调优实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(32)
- 最新
- 精选
- nightmareClass•forName有重载方法可以指定是否需要初始化,而默认的方法初始化设置为true这会初始化类执行链接和初始化操作,而ClasaLoader是有类加载器的loadClass方法加载,传入的是false只会执行链接操作,而不会执行初始化操作
作者回复: 回答非常详细
2019-07-11350 - QQ怪看老师这篇分享花了1个小时,分享的干货很多,回答下老师的问题: 不同点: 1)Class.forName()除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块,还会执行给静态变量赋值的静态方法。 2)classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
作者回复: 这次内容确实有点多,慢慢消化。
2019-07-12229 - -W.LI-这其实是因为由于 HotSpot 虚拟机目前的实现导致栈上分配实现比较复杂。 栈上分配影响: 1.java只有值传递,跨方法的局部变量在栈上分配的话,在现有栈实现上会影响栈的回收。 2.栈属于线程所有,实现栈上分配,会消耗更多的内存。让java的多线程更吃内存。 3.如果实现栈上分配,还需要GC作用会弱化很多吧。 4.基类型栈上分配+引用类型堆分配->全栈上分配。这么实现的话hotspot感觉全推翻了。 老师好有理解的不对的请指出谢谢
作者回复: W.LI同学解释的很透彻,赞一个。
2019-07-13215 - 天天向上文中讲到:逃逸分析如果发现一个对象只在方法中使用,就会将对象分配在栈上。然而我们的程序大多数对象都是只在方法中使用的啊,那栈就得需要很大的空间了啊??
作者回复: 使用方法时间非常短,所以在栈上的数据也就很快被释放掉了
2019-12-293 - 天信很困惑线上服务的时候如何去调整这些参数达到最优解,比如调整 ComplieThrehold 大小或者其它参数,以及调整后到如何计算收益呢
作者回复: 一般情况下我们不会去调整这些参数,JVM默认值就已经可以满足大多数服务了,使用默认值即可。
2020-01-0722 - SDL差了很多文章 还是没能找到在哪设置这些参数呢 望老师告知一下小白
作者回复: springboot jar启动文件下,在启动时设置JVM参数就好了,java -xx(jvm参数)-jar xxx.jar
2019-09-252 - 尔冬橙老师,Javap反编译的内容是生成class文件的中间过程么(在变成二进制文件前的汇编)
作者回复: class文件是字节码,再JIT 或解释器会将字节码转换成机器码
2020-03-0421 - Liam栈上分配这里,对局部变量对象的大小是否有要求,毕竟栈的内存比较小
作者回复: 目前hotspot虚拟机暂时不支持栈上分配对象。
2019-07-111 - 我又不乱来Class.forName加载类的时候会对类进行初始化,如静态代码块,ClassLoader 不会做初始化。spring做类加载的时候应该用的是ClassLoader把。超哥。
作者回复: 正确
2019-07-111 - 尔冬橙在非线程安全的情况下,尽量不要使用线程安全容器?这句话是不是线程安全的情况下?
作者回复: 是非线程安全,有时候非线程安全使用线程安全容器反而增加了性能开销
2019-09-023
收起评论