深入浅出JVM之执行引擎的解释执行与编译执行
本篇文章围绕执行引擎,深入浅出的解析执行引擎中解释器与编译器的解释执行和编译执行、执行引擎的执行方式、逃逸分析带来的栈上分配、锁消除、标量替换等优化以及即时编译器编译对热点代码的探测执行引擎
hotspot执行引擎结构图
执行引擎分为解释器、JIT即时编译器以及垃圾收集器
执行引擎通过解释器即时编译器将字节码指令解释编译为对应OS上的的机器指令
本篇文章主要围绕解释器与即时编译器解释执行与编译执行
Java虚拟机执行引擎在执行Java代码时,会有两种选择:解释执行和编译执行
解释执行:通过字节码解释器把字节码解析为机器语言执行
编译执行:通过即时编译器产生本地代码执行
Class文件中的代码到底是解释执行还是编译执行只有Java虚拟机自己才能判断准确
编译过程
经典编译原理:1。对源码进行词法,语法分析处理2。把源码转换为抽象语法树
javac编译器完成了对源码进行词法,语法分析处理为抽象语法树,再遍历抽象语法树生成线性字节码指令流的过程
剩下的指令流有两种方式执行由虚拟机内部的字节码解释器去将字节码指令进行逐行解释(解释执行)或优化器(即时编译器)优化代码最后生成目标代码(编译执行)执行引擎流程图
解释器与编译器
解释器
作用:对字节码指令逐行解释
优点:程序启动,解释器立即解释执行
缺点:低效
即时编译器(justintimecompiler)
Java中的编译期不确定可能说的是执行javac指令时的前端编译器(。java。class)也可能是后端编译器JIT(字节指令机器指令)还可能是AOT编译器(静态提前编译器)(。java机器指令)
作用:将方法编译成机器码缓存到方法区,每次调用该方法执行编译后的机器码
优点:即时编译器把代码编译成本地机器码,执行效率高,高效
缺点:程序启动时,需要先编译再执行执行引擎执行方式
执行引擎执行方式大致分为3种
Xint:完全采用解释器执行
Xcomp:优先采用即时编译器执行,解释器是后备选择
Xmixed:采用解释器即时编译器
hotspot中有两种JIT即时编译器
Client模式下的C1编译器:简单优化,耗时短(C1优化策略:方法内联,去虚拟化,冗余消除)
Server模式下的C2编译器:深度优化,耗时长(C2主要是逃逸分析的优化:标量替换,锁消除,栈上分配)
分层编译策略:程序解释执行(不开启逃逸分析)可以触发C1编译,开启逃逸分析可以触发C2编译
解释器,C1,C2编译器同时工作,热点代码可能被编译多次
解释器在程序刚刚开始的时候解释执行,不需要承担监控的开销
C1有着更快的编译速度,能为C2编译优化争取更多时间
C2用高复杂度算法,编译优化程度很高的代码逃逸分析带来的优化
当对象作用域只在某个方法时,不会被外界调用到,那么这个对象就不会发生逃逸
开启逃逸分析后,会分析对象是否发生逃逸,当不能发生逃逸时会进行栈上分配、锁消除、标量替换等优化栈上分配内存Xms1GXmx1GXX:PrintGCDetailspublicclassStackMemory{publicstaticvoidmain(String〔〕args){longstartSystem。currentTimeMillis();for(inti0;i10000000;i){memory();}System。out。println(花费时间:(System。currentTimeMillis()start)ms);try{TimeUnit。SECONDS。sleep(1000);}catch(InterruptedExceptione){e。printStackTrace();}}privatestaticvoidmemory(){StackMemorymemorynewStackMemory();}}
XX:DoEscapeAnalysis花费时间:63ms(未开启逃逸分析)
XX:DoEscapeAnalysis花费时间:4ms(开启逃逸分析)
默认开启逃逸分析锁消除
同步加锁会带来开销
锁消除:当加锁对象只作用某个方法时,JIT编译器借助逃逸分析判断使用的锁对象是不是只能被一个线程访问,如果是这种情况下就不需要同步,可以取消这部分代码的同步,提高并发性能标量替换
标量:无法再分解的数据(基本数据类型)
聚合量:还可以再分解的数据(对象)
标量替换:JIT借助逃逸分析,该对象不发生逃逸,只作用于某个方法会把该对象(聚合量)拆成若干个成员变量(标量)来代替
默认开启标量替换publicclassScalarSubstitution{staticclassMan{intage;intid;publicMan(){}}publicstaticvoidcreateInstance(){ManmannewMan();man。id123;man。age321;}publicstaticvoidmain(String〔〕args){longstartSystem。currentTimeMillis();for(inti0;i10000000;i){createInstance();}System。out。println(花费时间:(System。currentTimeMillis()start)ms);try{TimeUnit。SECONDS。sleep(1000);}catch(InterruptedExceptione){e。printStackTrace();}}}Xmx200mXms200mXX:PrintGCDetailsXX:DoEscapeAnalysis设置开启逃逸分析XX:EliminateAllocations设置不开启标量替换开启逃逸分析关闭标量替换:花费时间:93ms开启逃逸分析开启标量替换:花费时间:6ms热点代码与热点探测
JIT编译器并不是编译所有的字节码,JIT编译器只编译热点代码
热点代码:被多次调用的方法或方法中多次循环的循环体
栈上替换(OSR):JIT将方法中的热点代码编译为本地机器指令(被多次执行的循环体)
编译对象都是方法,如果是栈上替换则入口在方法的循环体开始那里
热点探测功能决定了被调用多少次的方法能成为热点代码
hotspot采用基于计数器的热点探测方法调用计数器:统计方法调用次数回边计数器:统计循环体执行循环次数
方法调用时先判断是否有执行编译后的机器码,有则直接使用方法区的Codecache中的机器码;没有机器码则判断计数器次数是否超过阈值,超过则触发编译,编译后机器码存储在方法区Codecache中使用;最后都没有就使用解释执行总结
本篇文章将围绕执行引擎,深入浅出的解析执行引擎中的解释器、即时编译器各自执行的优缺点以及原理
执行引擎由解释器、即时编译器、垃圾收集器构成,默认情况下使用解释器与编译器的混合方式执行
即时编译器分为C1、C2编译器,其中C1编译快但优化小,C2开启逃逸分析使用栈上分配、锁消除、标量替换进行优化,编译耗时但是优化大
即时编译器并不是所有代码都编译,而是使用方法技术和循环计数来将热点代码编译成机器码存放在方法区的CodeCache中
在混合执行的模式下,解释器、C1、C2编译器同时工作,分层编译
富养自己的8个习惯,遇见更好的自己所有的惊艳,都来自长久的准备。学会关注自己,学会更新自己。尽情享受生活的美好,不断丰盈生命的底色,才不负来这人间一趟。1主动学习。这个是进入社会后自己应该要有的一种态度,进入工作状
抄书打卡41抄书赚钱,不知道今天能有多少收益昨天收益0。03元,阅读量200多,离1000还需努力努力。今天摘抄的内容是与人相处适当的服软,合理的装傻,永远保持内心的清醒我们习惯于滔滔不绝说话说个不停,有时语气还会戳戳逼人的
失意中年男人的慈祥,我懂,但不多前一阵子火了一个视频中年男人正在走向慈祥,一个刚从大厂被优化朋友推荐给我,他说他的眼里有安静有慈祥,同样也是已经没有光。我完整看了一遍视频确实感到一些刺痛,失意中年大厂辞退,特别是
一切源于自己自己是一切的根源。如果你觉得国家不够好,那就去建设它。如果你觉得政府机构不行,那就去考公务员做官完善它。如果你觉得人民没素质,那就从自己开始做个高素质公民带动他。如果你觉得同胞愚昧
我在岛屿读书迷茫作为一种情绪,一种状态,很正常。会在做一件事的时候忽然懵掉,不知道为什么做,不知道为什么要接着做。可能在日落以后,面对着屏幕和闪烁的头像,会发一个无止尽的呆。我知道,我知道此时
王菲不当明星当普通人!穿老式大妈裙打扮这么俗套,气质还是高级如今王菲已经不想当明星了,完全是一个普通人的模样,你可能在当街看到她的时候都不知道他是谁。可能每个人的想法不一样吧,而且王菲想要过上普通的生活,所以现在日常生活中看到她也是老大妈的
LV这些高级感男包也太绝了吧回头率99关注时尚的朋友肯定对LV这个牌子不陌生,不管是男包还是女包LV都有很多拿得出手的佳作。LV每一季的设计都在不停突破,LV的男包也是很多男士的不二选择。本期就跟着小编一起来欣赏一下L
比黑色大衣更时髦高级,今冬驼色大衣火了嗨,各位小仙女们,大家好呀!说起冬天最受宠的外套是什么,Lily相信很多人的脑海里都忍不住想起大衣,因为这么一件单品真的很时尚耐看,也不挑人!在选择大衣颜色上,你或许会首选黑色灰色
我对黑丝的偏见,看到国外街拍后变了,搭配大衣原来这么高级每年一到寒冷的冬季,大家都在想方设法的如何穿好看?可是堆积起来的单品,不仅很容易显得臃肿,并且还会杂乱无章,所以我们现在要考虑的,就是选择保暖又时髦的时尚单品,比如黑丝!很多人对于
真正见过世面的女人年纪大了,衣服选长爱露脚踝,气质更高级头条创作挑战赛女人的穿衣打扮不仅受到潮流变化影响,也取决于眼界审美与品味,可以说,那么打扮优雅时尚的女人,给人的感觉就很不一般。特别当下时尚多元化,要想穿出好气质,更看重你的眼界。
我感觉我每天都活在崩溃的边缘我是宝妈一枚,在家里带着两个孩子,一个读二年级,一个读幼儿园。生下他们后,我本来就身体一直都不好,没什么精力管他们,再加上脾气特别容易暴躁,更是听不得孩子的吵闹和哭声。调皮捣蛋是孩