即时编译(分层编译/逃逸分析)
2021-02-26 15:12:40 0 举报
AI智能生成
即时编译(分层编译/逃逸分析)
作者其他创作
大纲/内容
即时编译器
just in time
just in time
背景
Java程序最初都是通过解释器进行解释执行的,当虚拟机发现某个方法或某个代码块运行特别频繁时,
就会把这些代码认定为“热点代码”,为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代
码编译成本地机器码,并以各种手段尽可能地进行代码优化,运行时完成这个任务的就是即时编译器
就会把这些代码认定为“热点代码”,为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代
码编译成本地机器码,并以各种手段尽可能地进行代码优化,运行时完成这个任务的就是即时编译器
种类
C1编译器 -client
(客户端编译器)
(客户端编译器)
1、需要收集的数据比较少
2、编译、优化方面都做得比较浅
3、编译生成的代码执行效率没 C2 高
4、编译时耗费的 CPU 资源没 C2 高
2、编译、优化方面都做得比较浅
3、编译生成的代码执行效率没 C2 高
4、编译时耗费的 CPU 资源没 C2 高
C2编译器 -server
(服务端编译器)
(服务端编译器)
1、需要收集的数据比较多(此为触发条件)
2、优化得更彻底(分析后做优化)
3、编译时耗费 CPU 资源
4、执行效率更高
2、优化得更彻底(分析后做优化)
3、编译时耗费 CPU 资源
4、执行效率更高
分层编译技术
背景
由于即时编译器编译本地代码需要占用程序运行时间,编译出优化程度越高的代码,所花时间也越长
为了在程序启动响应速度与运行效率之间达到最佳平衡,HotSpot虚拟机在 jdk 6 实现了分层编译
原理
解释器、客户端编译器和服务端编译器会同时工作,热点代码可能会被多次编译,
用客户端编译器获取更高的编译速度,用服务端编译器来获取更好的编译质量
用客户端编译器获取更高的编译速度,用服务端编译器来获取更好的编译质量
应用:系统启动初期的字节码优化采用C1,热机后采用C2编译器
阿里案例
热机切冷机故障
冷机:刚启动
热机:运行了一段时间
问题:并发性能快到瓶颈时,扩充了几台机器,然后把流量切过去,结果发现冷机崩了
原因:热机已经触发了C2编译器,生成了更优的字节码,承受的并发能力比冷机大很多
解决:先切部分流量过去,等触发C2编译器后,再把大流量切过去
触发条件
热点代码
多次执行的代码块
客户端模式下是1500次
服务端模式下是10000次
多次执行的方法
热点探测方式
基于采样的热点探测
基于计数器的热点探测
热度衰减
优化
方法内联
逃逸分析
点击跳转 👉
公共子表达式消除
数组边界检查消除
面试题
字节
问题
问题
Object obj = new Object();
这个对象占多少字节?
这个对象占多少字节?
占用16字节(B)jdk6 以后默认开启 指针压缩(-XX:+/-UseCompressedOops)
开启:MarkWord(8B)+KlassPoint(4B)+数组长度0+实例数据0+对齐填充4B的0
关闭:MarkWord(8B)+KlassPoint(8B)+数组长度0+实例数据0+对齐填充0
Int[] arr = {0,1,2};
这个数组对象占多少字节?
这个数组对象占多少字节?
开启是32字节:MarkWord(8B)+KlassPoint(4B)+数组长度4B+实例数据12B+对齐填充4B
关闭是40字节:MarkWord(8B)+KlassPoint(8B)+数组长度4B+头部填充4B+实例数据12B+对齐填充4B
依据
HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说任何对象的大小都必须是8字节的整数倍
一般情况下,对象头中的MarkWord占8字节,KlassPoint开启指针压缩占4字节(默认开启),如果对象为数组,则数组长度占4字节,
实例数据根据数据类型做具体判断,如果实例数据是引用类型:开启指针压缩占4字节,不开启占8字节,对齐填充补满8的倍数
实例数据根据数据类型做具体判断,如果实例数据是引用类型:开启指针压缩占4字节,不开启占8字节,对齐填充补满8的倍数
对象
个数
个数
String str = "silver";
在JVM中创建了几个String对象?
在JVM中创建了几个String对象?
创建1个String对象,先在字符串常量池中创建"sliver"对象,然后将该对象的引用赋值给str
String str2 = new String("cool"); 呢?
常量池中如果有"cool"则创建1个String对象,如果没有,则创建2个String对象
0 条评论
下一页