JVM的整体结构
JVM运行的位置
Jvm的结构
之前我们的学习 更倾向于 是用 API 现在我们的学习更加的底层 倾向于最底下的部分。
前端编译器: Javac(.java -> .class)
后端虚拟机 :hotspot client and server VM
HotSpotVm 结构
Hot Spot VM 是目前市面上高性能虚拟机的代表作之一
他采用解释器与即时编译器并存的架构
在今天 java程序的运行性能已经可以达到和C/C++程序比较的地步了
Java代码的执行流程
生成字节码文件 先从源码 走到 编译器 最后生成 Class 字节码文件
到了 虚拟机 首先是: 类加载器 - > 字节码校验器 -> 执行引擎(编译器(针对热点代码,总是要执行的)或者翻译字节码(解释器)执行)
JVM架构模型
Java 编译器输入的指令流基本上是一种基于栈道指令集架构 另外一种指令集则是基于寄存器的指令集架构
两种架构的区别就是 :
基于栈式架构的特点
设计和实现更简单 更适用于资源受限的系统
避开了寄存器的分配难题,使用零地址指令方式分配
指令流中的指令大部分都是零地址指令,其执行的过程主要依赖与操作栈,指令集更小
不需要硬件支持,可移植性更好,更好的实现跨平台
基于寄存器的特点
典型的应用就是 x86 的二进制指令集,比如传统的PC 以及安卓的Davlik 虚拟机
指令集架构完全依赖硬件,可移植性差
性能够优秀 执行更高效
话费更少的指令去完成一项操作
在大部分情况下 基于寄存器的指令集往往都以一地址指令 二地址指令和 三地址指令为主,基于栈式架构的指令集往往以零地址的指令集为主
反编译实践
查看编译后的字节码文件,是如何的
public static void main(String[] args) {
int i = 2;
int j = 3;
int k = i + j;
}
反编译的结果
思考总结
现在跨平台的设计 java 的指令 都是根据栈来设计的,不同平台的cpu 架构不同,所以不能设计基于寄存器的 优点是 跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令
时至今日 尽管嵌入式瓶盖已经不是java 程序的主流运行平台,(准确的来说 Host Spot VM 对于宿主的环境已经布不局限于嵌入式平台了) 那么为什么不讲 架构更换成 速度更快的 寄存器架构呢?
答 : java指令执行 是 基于栈的架构 设计的,再受限的环境(嵌入式环境)和非受限环境都可以有不错的反响,所以基于有点 不需要更换架构
JVM生命周期
虚拟机的启动
Java 虚拟机的启动 是引导类加载器 bootstarp class loader 创建一个初始类(initial class )来完成的
这个类是由虚拟机了来具体实现的
虚拟机的执行
一个运行中的java 虚拟机有着一个清晰的任务 就是 :执行java 程序
程序执行的时候 他开始运行 程序结束的时候 他停止
执行一个所谓的java程序的时候 其实真真正正的执行的是一个叫做java 虚拟机的线程
实例
还是以刚才的代码为例子
查看java进程命令 : jps
来查看执行中的java程序
可以看到我们在执行的程序.
代码
public class StackStruTest { public static void main(String[] args) { int i = 2; int j = 3; int k = i + j; try { TimeUnit.SECONDS.sleep(10); } catch (Exception e) { e.printStackTrace(); } System.out.println("hello"); } }
执行之后主线程会 睡眠 10 秒,此时用 jps 命令来查看线程,可以看到我们执行的程序
输出 hello 之后 下次查看 就会发现 执行完成了 刚才的类名线程就停止了
虚拟机的退出
有如下几种情况:
程序正常执行结束
程序在执行中遇到了 异常 或者错误终止
由于操作系统出现了错误 导致 Java 虚拟机 进程终止
某线程调用 runtime 类或者 system 类的 exit 方法 或者是 runtime 类的halt 方法 并且 Java 安全管理器也允许这次exit 或者 halt 操作
除此之外 JNI(Java native interface ) 规范描述了 JNI Invocation API 加载或者卸载,Java 虚拟机时。java虚拟机的退出情况
代码操作退出
不管是 System 还是 runTime 调用到最后都是 shutDown 类中的 halt的halt 方法 来调用 halt0本地方法来结束进程
/* The halt method is synchronized on the halt lock * to avoid corruption of the delete-on-shutdown file list. * It invokes the true native halt method. */ static void halt(int status) { synchronized (haltLock) { halt0(status); } }
JVM 发展历程
Sun Classic VM
简介
早在 1996 年 Java 1.0 版本 的时候 Sun 公司 发布了一款名为Sun Classic VM 的 Java 虚拟机 它同时也是世界上第一款 Java 虚拟机 ,在 Java 1.4 的版本中 被淘汰
**特点: 这款虚拟机内部只提供解释器不提供 JIT **
如果需要使用JIT 需要外挂,但是一旦使用了JIT编译器,JIT就会接管虚拟机状态的执行系统,解释器将不在工作,解释器不能和编译器配合工作 现在都 hotspot VM内置了此虚拟机
Exact VM
简介
为了解决上一个虚拟机的问题DK 1.2 的以后 sun 提供了此虚拟机
Exact Memory Management 准确式内存管理
也可以叫 Non - Conservative /Accurate Memory Management
虚拟机可以准确的知道内存中某个位置的数据 具体是什么类型
特点:
热点代码编译探测
编译器与解释器可以混合工作
不过只在 SUN公司自己的服务器上使用 ,还没有大展身手 被 hotspot VM替换
HotSpot VM
HotSpot VM 历史:
简介
最初是一家叫做 Longview Technologies 的小公司
1997 这个公司被 sun收购,2009年 sun 被甲骨文收购
JDK 1.3 的时候 Hotspot VM 成为默认虚拟机
此后 所有的版本默认都是使用的HotSpot VM虚拟机
特点:
通过计数器 找到最具编译价值的代码,出发即时编译或者栈上编译
通过编译器与解释器同时协作,在最优化的程序响应时间与最佳的执行性能中取得平衡
BEA JRockit
简介
JRockit 专注于服务器端,这个虚拟机不关注程序的启动速度,因此 JRockit 内部不包含解释器实现,全部代码,都靠即时解释器后执行,
大量测试基准:JRockit 是世界上 最快的虚拟机,使用JRockit速度显著提高(70%),硬件上也有成本的减少(50%)
优质特点:
JRockit 面向延迟敏感性应用提供解决方案 JRockit real time 提供以毫秒或者微秒级别的JVM响应时间,适合财务,军事指挥,电信网络等需求
MissionControl工作套件,它是一组以极低开销来监控,管理 , 分析生产环境中的应用工具
2008 年 BEA 被甲骨文收购
优化:
甲骨文整合了两大虚拟机的优势,在JDK 8中 在Hotspot 基础上 整合了JRockit 的优秀特性
IBM J9
简介
全称叫 : IBM Technology for java Virtual Machine 简称IT4J内部代号 J9
应用场景 : 服务端,桌面,嵌入式等
广泛用于 IBM的各种Java 产品
目前 最有影响力的三大商用虚拟机之一,也号称是世界上最快的Java虚拟机,
2017左右 有影响力 J9 VM 命名为 OpenJ9 交给 Eclipse 会管理 也成为 Eclipse OpenJ9
Apache Harmony
简介
Apache 也曾经退出过JDK 1.5 和 JDK1.6 兼容的Java运行平台 Apache Harmony
它是 IBM和intel 联合开发的开源 JVM 受到同样开源的 OpenJDK 压制,SUN坚决不给Harmony
获得JCP认证,最终 2011 年 停止,IBM转而参与 OpenJDK
虽然没有大规模商用,但是它的类库被安卓SDK 吸纳,继续发光发热
Microsoft JVM
简介
微软为了 ie3 浏览器 Java Applets 开发了 Microsoft JVM 只能再 window 平台运行 但确是win端 性能最好用的JVM
特点:只能在Microsoft平台运行
1997 Sun以侵犯商标和不正当竞争指控微软成功,导致微软赔了很多钱,最后再 win环境中移除了Microsoft JVM
Dalvik VM
简介
谷歌开发的 应用于安卓系统 并且在 安卓 2.2 中提供了JIT 发展迅猛,Dalvik VM只能做虚拟机,而不能称作java虚拟机,因为它没有遵守java虚拟机的规范
区别 不能直接执行Java CLass
基于寄存器架构 不是JVM的栈架构
执行的是编译以后的dex文件,执行效率较高,
这个dex : 可以通过class转换成dex 使用java语法来编写应用程序,可以直接使用大部分都Java API等
不过再 安卓 5.0 已经替换成了 ART VM
Graal VM
简介
2018年四月份 甲骨文 公开了 Graal VM号称 Run Programs Faster Anywhere(使用任何的程序在任何场景更快)
与 1995 年的 编写一次 任意运行 遥遥呼应,
特性
怎正意义上的全栈虚拟机 可以作为任何语言的运行平台使用
支持不同语言中混用对方的接口和对象,支持这些语言已经编写好的本地库文件
工作原理是将这些语言的源代码或者源代码编译后的中间格式,通过转换器转为能被 Graal VM接受的中间标识,Graal VM提供Trffle工具快速构建面向一种语言的解释器,在运行的时候还可以即时编译优化,获得比原生编译器更优秀的效率
如果有一天 Hotspot VM会被替代 最有机会的就是 Graal VM但是替换的过程中 不会影响Java软件生态的一分一毫