@author Kode
@date:2018年6月28日11:02
第五期:JVM-HotSpot虚拟机-即时编译器、编译优化等相关知识。
这一部分怎么理解呢?我觉得应该找个主线把它串起来。
估计很多人都思考我们写的程序是怎么驱动电脑运行的,今天我们就以Java为例来说道说道。
打开IDEA,写了.java程序,一运行,生成.class文件,然后再运行这个文件,最后展示出我们想要的结果。
第一步:先看看.java是怎么变成.class的?
这个时候就得需要一个专业名词了,编译。那么编译是什么呢?编译就是将源程序翻译成可执行的目标代码。 .java文件经过处理后变成.class文件这一过程就可以理解为编译。那么这一过程是怎么样的呢?
过程
.Java文件 –> 词法分析器 –> 语法分析器 –> 语义分析器 –> .class 文件
第二步:得到.class文件以后,怎么输出我们想要的结果?
现在有了class文件以后,那我们怎么让它解释并运行呢?这个时候就得介绍一下类加载过程和机制了。
class文件 –> 加载 –> 验证 –> 准备 –> 解析 –> 初始
类加载机制就是:双亲委派模型了
在解释这一过程,我们可能需要先了解一下一个专有名词:解释,编译和解释两个名词也说明了Java语言的特性。那么什么是解释呢? 解释就是将.class文件逐条读入,逐条翻译解释,大白话就是一步一步来。这样的话会有什么缺点?Java是怎么解决的呢?
缺点是:执行效率比较差,这也算是解释性的语言的通病。
解决办法:这个时候就得掌声欢迎 JVM 和 JIT(Just in time)技术大佬登场,他们协作着把这个问题解决了。如何提高性能,那就通过优化。那怎么优化呢?这个时候就需要JVM帮忙了,JVM会通过观察方法和代码块运行的次数来决定是不是把这些代码块和方法标记成热点代码,然后JIT会把标记的热点代码翻译成本地相关的机器码,并进行优化,然后缓存起来,以备下次之用。这里面有点像数据库中的存储过程。在这里有个疑问,JVM是怎么判别方法和代码块是不是热点代码?
1, 基于采样的方式探测
2,基于计数器的热点探测
常用的计数器的热点探测两个方法:方法计数器、回边计数器JIT是怎么优化的呢?
逃逸分析、 锁消除、 锁膨胀、 方法内联、 空值检查消除、 类型检测消除、 公共子表达式消除
参考资料:
[1] 深入浅出 JIT 编译器
[2] 什么是即时编译(JIT)!?OpenJDK HotSpot VM剖析
[3] 对象和数组并不是都在堆上分配内存的。-HollisChuang’s Blog