JVM(八)执行引擎相关内容
一:两种解释器
JAVA字节码解释器:
java字节码===》c++代码==》硬编码。
首先.java文件编译成字节码,遍历每行的字节码指令,因为每个字节码指令的含义都是固定的所以可以根据每行字节码指令来转成c++代码调用,最后转成硬编码(机器码)来执行。
模板解释器:
由java字节码==》硬编码。可以从java字节码直接到硬编码。
模板解释器底层实现流程:
1)申请一块内存:可读可写可执行
2)将处理new字节码的硬编码(举个例子)拿过来,可以通过解析文件得到
3)将处理new字节码的硬编码写入申请的内存
4)申请一个函数指针,用这个函数指针执向这块内存
5)调用的时候,直接通过这个函数指针调用就可以了。
Mac中是无法使用JIT的!因为Mac无法申请一块可读可写可执行的内存块
二:三种运行模式
-Xint 纯字节码解释器
-Xcomp 纯模板解释器
-Xmixed 字节码解释器+模板解释器
默认是mixed,可以通过java -version查看
混合模式
纯字节码解释器
纯模板解释器:
三:三种运行模式的性能
1:-Xint 纯字节码解释器, 解释一行执行一行,其实属于解释执行了。如果代码多的话肯定效率不会太高。
2:-Xcomp 纯模板解释器,需要把.class编译成硬编码之后再执行,如果程序很大,启动时间耗时可能会较久。
3:-Xmixed 字节码解释器+模板解释器,所以现在都是混合模式的编译。刚启动的时候采用字节码解释器,这样只要解析执行启动相关的代码即可,等到程序运行一段时间之后,即时编译器收集到的代码越来越多就可以使用模板解释器提高运行效率。
2,3那个性能比较高,主要看程序的规模了。
四:模板解释器使用的硬编码谁来编译呢?编译后又是放在哪里呢?
即时编译器:属于JIT技术。
1)C1即时编译器。
c1编译器是client模式下的即时编译器。现在64bit机都是server模式了
(1)触发条件比C2宽松,需要收集的数据较少。
(2)编译的优化比较浅比如:基本运算在编译的时候运算掉了或这final 修饰的字符串的优化。
(3)c1编译器编译生成的代码执行效率比c2低些。
就算对其进行调优,性能的提升曲线也很平缓。
2)C2编译器
c2编译器是server模式下的即时编译器。
(1)触发的条件比较严格,一般来说,程序运行一段时间以后触发。
(2)优化的比较深。比如编译的时候判断操作是否设计到堆栈,如果没有的话直接优化掉了。
(3)编译生成的代码执行效率比c1更高。
3) 混合编译
jdk6以前是没有混合编译的,后来根据两种编译器的使用场景组合起来使用进一步提升性能
程序运行初期触发c1编译器,程序运行一段之后触发c2编译器。
这里说明一点:
字节码解释器是解释执行的,和即时编译器无关。
模板解释器执行的硬编码就是即时编译器编译的。
即时编译触发的条件!
硬编码在jvm中称为热点代码。
触发即时编译的最小单位不是一个函数,而是一个代码块(for,while等)
client模式下,默认值 1500。即一段代码执行1500次会触发即时编译。
server模式下,默认值是10000。即一段代码执行10000次会触发即时编译。
热度衰减:
有一段代码执行了7000次,还有3001次触发即时编译,但是在一定时间内,这段代码没有被调用,这个次数会以两倍速递减变成3500,这时候就需要再执行6501次才会触发即时编译。这种就叫热度衰减。
补充知识点!!!!!!!
热机切冷故障。
热机:就是已经运行了一段时间的机器。
冷机:就是刚运行的机器。
问题:
当给已经运行了一段时间的热机集群中增加一个节点冷机的时候,冷机起到负载均衡的作用,但是会出现冷机一上线就会挂掉。
原因:
热机中有热点代码缓存,抗的并发更大,冷机中一边运行程序一边触发即时编译占用cpu。
解决方案:
冷机切流量,慢慢切,等到触发即时编译了就可以正常负载了。
热点代码缓存区,在方法区。这块也是调优需要调的地方,但是一般不动。
java -XX:+PrintFlagsFinal -version | grep CodeCacheSize
server 编译器模式下代码缓存大小则起始于 2496KB
client 编译器模式下代码缓存大小起始于 160KB
五:即时编译器是如何运行的
即时编译时通过VM_Thread线程执行的
1:将即时编译器任务写入队列
2:VM_THREAD从这个队列中读取任务并执行。
异步执行的。
可以查看编译线程有多少个?如果有必要可以调整这个大小。
java -XX:+PrintFlagsFinal -version | grep CICompilerCount
六:如何理解java是半解释半编译型语言
1:javac 编译java文件,java运行
2:字节码解释器解释执行,模板解释器编译执行。
七:逃逸分析
逃逸:对象逃逸,直接解释逃逸不如直接说明不逃逸更直观。逃逸的话,对于对象如果是共享变量,返回值,参数,则对象是逃逸的,就是逃到了线程外,方法外。
对象不逃逸:对象的作用域是局部变量,对象就是不逃逸的。
-XX:+DoEscapeAnalysis//开始逃逸分析 -XX:-DoEscapeAnalysis//禁用
基于逃逸分析,JVM开发了三种优化技术:
栈上分配:
逃逸分析开启,栈上分配就是存在的,逃逸分析默认是开启的。我们可以测试下看栈上分配的存在。
我们在堆中创建20万个对象,如果堆里这个对象少于20个,说明有在栈上分配的。前提不会发生GC。
我们先测试只在堆上创建,我把逃逸分析关闭了。
public static void main(String[] args) {
for (int i = 0; i <200000 ; i++) {
DriverDemo s1= new DriverDemo();
}
while (true);
}
执行之后,我们通过HSDB查看堆中创建了多少个对象。java -cp sa-jdi.jar sun.jvm.hotspot.HSDB 。首先查找jvm线程。在HSDB中打开线程id.
看到堆里有20万个对象。说明此时没有发生栈上分配。
我们把逃逸分析打开再执行查看HSDB。此时堆中对象已经少于20万个了,所以出现了栈上分配。
标量替换:
标量:是不可拆分的变量,java中的基本数据类型就是标量的。
scalar replacement。Java中的原始类型无法再分解,可以看作标量(scalar);指向对象的引用也是标量;而对象本身则是聚合量(aggregate),可以包含任意个数的标量。如果把一个Java对象拆散,将其成员变量恢复为分散的变量,这就叫做标量替换。拆散后的变量便可以被单独分析与优化,可以各自分别在活动记录(栈帧或寄存器)上分配空间;原本的对象就无需整体分配空间了
聚合量:是可拆分的,就是引用数据类型。
锁消除:
锁消除是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行削除。锁削除的主要判定依据来源于逃逸分析的数据支持,如果判断到一段代码中,在堆上的所有数据都不会逃逸出去被其他线程访问到,那就可以把它们当作栈上数据对待,认为它们是线程私有的,同步加锁自然就无须进行。
比如下面这段代码就会在编译的时候把同步锁去掉。
synchronized (new Object()){
System.out.println("ddd");
}
JVM(八)执行引擎相关内容的更多相关文章
- jvm虚拟机---执行引擎子系统
Java虚拟机只与Class文件相关联,它规定了Class文件应该具有的格式,而不论该文件是由什么语言编写并编译而来.所以,任何语言只要能够最终编译成符合Java虚拟机要求的Class文件,就可以运行 ...
- JVM调优一些相关内容
JVM调优工具 Jconsole,jProfile,VisualVM Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回收算法有很详细的跟踪.详细说明参考这里 ...
- 【JVM第七篇】执行引擎
写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 执行引擎是Java虚拟机中的核心组成部分. 执行引擎的作用就是解析虚拟机字节码指令, ...
- 一夜搞懂 | JVM 字节码执行引擎
前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 GIthub 博客 学习导图 一.为什么要学习字节码执行引擎? 代码编译的结果从本地机器码转变为字节码,是存储格式发展的一 ...
- 执行引擎子系统——JVM之五
一.JVM通过执行引擎来完成字节码的执行,在执行过程中JVM采用的是自己的一套指令系统,每个线程在创建后,都会产生一个程序计数器(pc)和栈(Stack). pc:存放了下一条将要执行的指令: Sta ...
- 深入理解java虚拟机(5)---字节码执行引擎
字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...
- Java虚拟机执行引擎
执行引擎 关于执行引擎相关的部分, 在之前的博文里 Java内存区域中已经有所提及. 回顾一下: 也只有几个概念, JVM方法调用和执行的基础数据结构是 栈帧, 是内存区域中 虚拟机栈中的栈元素, 每 ...
- 深入理解java:1.2. 字节码执行引擎
执行引擎是Java虚拟机的核心组成部分之一. 首先,想想C++和Java在编译和运行时到底有啥不一样? 下图左边,C++发布的就是机器指令, 而下图右边Java发布的是字节码,字节码在运行时通过JVM ...
- JVM总结(五):JVM字节码执行引擎
JVM字节码执行引擎 运行时栈帧结构 局部变量表 操作数栈 动态连接 方法返回地址 附加信息 方法调用 解析 分派 –“重载”和“重写”的实现 静态分派 动态分派 单分派和多分派 JVM动态分派的实现 ...
随机推荐
- jq再次封装自己的ajax & js 回调函数 & js方法注释&js 全局屏蔽点击事件及a标签
1.封装成一个独立JS var commonUrl = 'http://xx.xxx.com/'; function http({ url, type = "post", data ...
- 【自定义轮播图】微信小程序自定义轮播图无缝滚动
先试试效果,可以通过设置参数调整样式 微信小程序中的轮播图可以直接使用swiper组件,如下: <swiper indicator-dots="{{indicatorDots}}&qu ...
- Linq基础知识
开发人员不需要关心将要访问的是关系数据库还是XML数据,或是远程对象,它都采用同样的访问方式. Linq包含一系列的查询技术,其中Linq到对象是对内存进行操作,LINQ到SQL是对数据库的操作,LI ...
- (五)cp命令复制文件或者目录
一.cp的含义.功能及命令格式 cp(英文copy的缩写)命令可以将一个文件或者目录从一个位置复制到另外一个位置.cp的功能就是将一个文件复制成 一个指定的目的文件或者复制到一个指定的目录中,兼具复制 ...
- 整合SSM框架
整合SSM 基本环境搭建 导入相关的pom依赖! <dependencies> <!--Junit--> <dependency> <groupId>j ...
- SpringBoot 的多数据源配置
最近在项目开发中,需要为一个使用 MySQL 数据库的 SpringBoot 项目,新添加一个 PLSQL 数据库数据源,那么就需要进行 SpringBoot 的多数据源开发.代码很简单,下面是实现的 ...
- spring mvc 集成quartz
首先quartz配置文件 # Default Properties file for use by StdSchedulerFactory # to create a Quartz Scheduler ...
- Mac苹果电脑安装虚拟机
Mac上的虚拟机推荐安装 Parallel Desktop For Mac 1.安装Parallel Desktop 2.下载Windows7 3.用Parallel Desktop安装Window ...
- LayUI表单提交不走ajax原因
在使用layui的时候.遇到一个问题.提交表单,没有走ajax,直接提交了表单页面. 原因是因为JQuery未引入 解决办法.引入JQuery或者使用layui自带Jquery var $ = lay ...
- python实现贴吧顶贴机器人
前言------百度贴吧流量如何?全球最大的中文社区,虽然比不上阿里,腾讯! 此文章仅供交流学习.建议机器人用小号操作,切勿用作商业用途! 测试版本:python 3.7 64位火狐浏览器firefo ...