Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

22 | 深入JVM即时编译器JIT,优化Java编译

刘超 2019-07-11
你好,我是刘超。
说到编译,我猜你一定会想到 .java 文件被编译成 .class 文件的过程,这个编译我们一般称为前端编译。Java 的编译和运行过程非常复杂,除了前端编译,还有运行时编译。由于机器无法直接运行 Java 生成的字节码,所以在运行时,JIT 或解释器会将字节码转换成机器码,这个过程就叫运行时编译。
类文件在运行时被进一步编译,它们可以变成高度优化的机器代码,由于 C/C++ 编译器的所有优化都是在编译期间完成的,运行期间的性能监控仅作为基础的优化措施则无法进行,例如,调用频率预测、分支频率预测、裁剪未被选择的分支等,而 Java 在运行时的再次编译,就可以进行基础的优化措施。因此,JIT 编译器可以说是 JVM 中运行时编译最重要的部分之一。
然而许多 Java 开发人员对 JIT 编译器的了解并不多,不深挖其工作原理,也不深究如何检测应用程序的即时编译情况,线上发生问题后很难做到从容应对。今天我们就来学习运行时编译如何实现对 Java 代码的优化。

类编译加载执行过程

在这之前,我们先了解下 Java 从编译到运行的整个过程,为后面的学习打下基础。请看下图:

类编译

在编写好代码之后,我们需要将 .java 文件编译成 .class 文件,才能在虚拟机上正常运行代码。文件的编译通常是由 JDK 中自带的 Javac 工具完成,一个简单的 .java 文件,我们可以通过 javac 命令来生成 .class 文件。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(16)

  • nightmare
    Class•forName有重载方法可以指定是否需要初始化,而默认的方法初始化设置为true这会初始化类执行链接和初始化操作,而ClasaLoader是有类加载器的loadClass方法加载,传入的是false只会执行链接操作,而不会执行初始化操作

    作者回复: 回答非常详细

    2019-07-11
    8
  • QQ怪
    看老师这篇分享花了1个小时,分享的干货很多,回答下老师的问题:
    不同点:
    1)Class.forName()除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块,还会执行给静态变量赋值的静态方法。
    2)classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。

    作者回复: 这次内容确实有点多,慢慢消化。

    2019-07-12
    7
  • -W.LI-
    这其实是因为由于 HotSpot 虚拟机目前的实现导致栈上分配实现比较复杂。
    栈上分配影响:
    1.java只有值传递,跨方法的局部变量在栈上分配的话,在现有栈实现上会影响栈的回收。
    2.栈属于线程所有,实现栈上分配,会消耗更多的内存。让java的多线程更吃内存。
    3.如果实现栈上分配,还需要GC作用会弱化很多吧。
    4.基类型栈上分配+引用类型堆分配->全栈上分配。这么实现的话hotspot感觉全推翻了。
    老师好有理解的不对的请指出谢谢

    作者回复: W.LI同学解释的很透彻,赞一个。

    2019-07-13
    4
  • 张德
    刘老师您好 听完这篇课程想起了以前去阿里面试一个面试官问到的问题 问题大概是 OSGI各个容器之间的类加载器是怎么进行隔离的 刘老师懂不懂 能不能回答一下 谢谢
    2019-07-20
    2
    3
  • 平凡之路
    学习了很多
    2019-11-28
  • SDL
    差了很多文章 还是没能找到在哪设置这些参数呢 望老师告知一下小白

    作者回复: springboot jar启动文件下,在启动时设置JVM参数就好了,java -xx(jvm参数)-jar xxx.jar

    2019-09-25
  • godtrue
    太干了,需要多点时间消化。老师这些知识,怎么持久化到脑袋里的,感觉自己脑袋里的知识都是分配在堆上的,很想放在MySQL数据库里。
    2019-09-11
    1
  • 疯狂咸鱼
    在非线程安全的情况下,尽量不要使用线程安全容器?这句话是不是线程安全的情况下?

    作者回复: 是非线程安全,有时候非线程安全使用线程安全容器反而增加了性能开销

    2019-09-02
    1
  • 王龙飞
    看了三遍,干货满满,老师辛苦
    2019-07-23
  • 梁中华
    据一些书上说,因为默写原因Hotspot JVM并没有实现逃逸分析的优化,不知道最新的JVM有没有实现这条优化。

    作者回复: 目前的资料来看,最新的JVM暂时没有实现。

    2019-07-15
  • 王世林
    class.forNam实现也调用ClassLoader. 不过class.forName有static静态代码块,在类初始化的过程中执行了静态代码块中的代码,例如jdbc的实现需要加载数据库驱动,在静态代码块中向DriveManager注册自己.Spring直接用的Classloader
    2019-07-14
  • bro.
    逃逸分析跟标量替换在JDK 6u23以上版本都是默认开启状态的

    作者回复: 是的

    2019-07-12
  • Wendy
    你好,刘兄!方便加下你微信吗?方便沟通

    作者回复: 你好 Wendy,平台暂时不支持我们加个人微信,有问题可以在这里沟通,或通过github中的邮箱沟通。感谢你的支持。

    2019-07-12
    1
  • undifined
    老师 这段代码没有懂

    static{
      i=0;
    }
    private static int i=1;
    public static void main(String [] args){
      System.out.println(i);
    }

    static代码块在类加载的时候执行,按照书写顺序,此时 i 还没有被声明,是怎么赋值的
    2019-07-11
    2
  • Liam
    栈上分配这里,对局部变量对象的大小是否有要求,毕竟栈的内存比较小

    作者回复: 目前hotspot虚拟机暂时不支持栈上分配对象。

    2019-07-11
  • 我又不乱来
    Class.forName加载类的时候会对类进行初始化,如静态代码块,ClassLoader 不会做初始化。spring做类加载的时候应该用的是ClassLoader把。超哥。

    作者回复: 正确

    2019-07-11
收起评论
16
返回
顶部