Java Virtual Machine: Java虚拟机,当Java编程的能力达到一个高度时,JVM的原理就要研究一下了。
本文主要了解JVM的基本知识和周边概要,为后续学习打下基础。
目前的Java是什么?
我们现在说的Java已经不仅仅指一门语言,而是指构建在JVM之上的一整套的JAVA开发平台,其包含了各种JVM语言,各种第三方Java生态框架,各种Java社区,各种Java类库,加上Java作为代表的一门语言。
- Java作为一种平台:JVM之上多种编程语言,构成了一个平台,Java不仅仅代表Java语言。
- Java作为一种文化:Java是“面向对象”和“开源”的开源的代名词,是一种开源文化,Java语言、JVM、乃至周边三方框架等等都是开源的。
- java作为一个社区:Java是世界上开发人数最多的编程语言,也拥有最庞大的开源社区支持。
Java能有以上的殊荣,其本质原因得益于其强大的虚拟机JVM,Java的跨平台,强安全性,高性能都来自于它的虚拟机,JVM是Java的核心。
JVM和Java的关系
Java语言或其他JVM语言,编译后生成字节码文件,字节码文件运行在JVM上。
Java不是最强大的语言,但是JVM是最强大的虚拟机。
JVM发展历程
- Sun Classic VM
- 1996年JDK1.0发布时,第一台商用虚拟机,JDK1.4时完全被淘汰
- Classic VM只提供解释器,此时的Java是解释执行的(逐行解释字节码文件为二进制指令交给操作系统执行),不提供JIT(即使编译:把字节码转换为二进制指令缓存起来,只解释一次,后续直接交由操作系统执行)
- 现在的Hotspot VM内置了Classic VM
- Exact VM
- Exact Memory Management 准确式内存管理,虚拟机可以知道内存中某个位置的数据具体是什么类型
- 特点探测,解释执行和JIT同时具备
- 只在Solaris平台短暂使用,后被Hotspot VM代替
- Hotspot
- 最初由Longview Technologies公司设计,1997年被Sun公司收购
- JDK1.3时,Hospot VM成为JDK默认虚拟机,主流,占有绝对市场地位
- Hotspot指的就是热点代码探测技术,即JIT技术,支持编译器和解释器协同,在最优程序响应时间和最佳执行性能之间取得平衡
- JRockit
- BEA公司的,后被Oracle公司收购
- 专注于服务器应用,不包含解释器,全部代码都靠JIT实现,启动慢但执行速度快
- 提供了MissionControl(JMC),一套极低的开销来监控、管理和分析JVM运行时应用
- J9
- IBM公司的J9 VM,IBM Technology for Java Virtual Machine,简称IT4J,内部代号J9
- J9只在IBM硬件上性能极好,其他硬件产品较差甚至有bug,支持不太友好
- 2017年,IBM开源了J9,命名为OpenJ9,交给Eclipse基金会
- Azul VM(Zing JVM)
- 特定硬件绑定、软硬件配合的专用虚拟机,性能极高
- 2010年 Azul Systems公式,发布自己的Zing JVM,可以在x86平台运行,性能极高
- Apache Harmony
- Apache也曾推出过与JDK1.5和JDK1.6兼容的JVM
- IBM和Intel联合开发的,未被大规模商用,但是却被Android SDK吸收核心类库
- Microsoft JVM
- 微软为了在IE3中支持Java Applets,开发了Microsoft JVM
- 只能在Windows上运行,在Windows下执行性能最好,后再1997年被Sun公司起诉侵权
- TaobaoJVM
- AliJVM团队发布,阿里基于OpenJDK开发的自己公司的JVM,是整个阿里系的基石
- 创新的GCIH(GC invisible heap)实现了off-heap,将生命周期较长的Java对象从heap中移到heap之外,不再GC,提升效率
- GCIH中的对象还可以在多个JVM进程中共享
- 使用crc32指令实现了JVM intrinsic降低JNI的调用开销
- 针对大数据场景的ZenGC
- taobao VM提升了性能,但严重依赖interl的CPU,损失了兼容性
- Dalvik VM
- 谷歌开发的VM,用于Android系统
- Dalvik VM未遵循JVM规范,不能成为严格意义上的Java VM,未使用栈架构,使用了寄存器架构,性能更快,但损失了兼容性
- Graal VM
- Oracle在2018年公开的虚拟机,号称“run programs faster anywhere”运行任何程序在任何地方都是最快的
- 是一款跨语言的全栈虚拟机,不仅仅支持Java系列语言,甚至支持c,c++,python,ruby,r等等语言
主流的JVM
- Hotspot VM:Oracle JDK和Open JDK默认虚拟机,主流虚拟机,我们平时说的JVM,一般就是指Hotspot VM
- J9 VM:IBM开源的J9虚拟机
- JRockit:也是一个性能极好的虚拟机,Oracle收购后,JRockit的一部分被整合到了Hotspot,大部分被废弃。
Java历史大事件
- 1990年,Sun公司开发了一门新语言,命名为Oak,后改名为Java。
- 1995年,Sun公司正式发布Java和HotJava虚拟机。
- 1996年,Sun公司正式发布JDK1.0.
- 1998年,Sun公司发布JDK1.2,同时发布了JSP/Servlet和EJB规范,将Java分为J2EE、JSEE、JMEE。
- 2000年,Sun公司发布JDK1.3,HotSpot成为默认虚拟机,延续至今。
- 2002年,Sun公司发布JDK1.4,Classic虚拟机退出历史舞台。
- 2004年,Sun公司发布JDK1.5,引入大量新功能,改名为Java5.0。
- 2006年,Sun公司发布JDK1.6,建立开源OpenJDK,HotSpot为默认虚拟机。
- 2008年,Oracle收购BEA,得到JROckit虚拟机。
- 2010年,Oracle收购Sun,得到Java和Hotspot虚拟机。
- 2011年,JDK7发布,正式启用G1垃圾回收器。
- 2014年,JDK8发布,引入函数式编程思想,同时Oracle改Java版本发布为6个月一次,Oracle JDK开始收费,OpenJDK仍然开源免费。
- 2017年,JDK9发布,G1设置为默认GC,取代CMS,同年IBM的J9开源。
- 2018年,Oracle状告谷歌的Java侵权案判决,谷歌败诉,赔偿88亿美元,同年Oracle宣布J2EE成为历史,发布JDK11,发布革命性的ZGC。
2019年,JDK12发布,加入Redhat领导开发的Shenandoah GC。
Oracle JDK和Open JDK
Oracle官方宣称,Oracle JDK和Open JDK除了开源协议之外,完全相同。
其实不同的版本,两个还是有略微小差别的,我们可以认为两者基本一样,一个收费一个免费。
JVM的作用
JVM是构建在操作系统之上的,二进制字节码的运行环境,用于解释执行字节码文件。
跨平台,一次编译,处处运行
- 自动内存管理
- 自动垃圾回收
总结:简化的编程过程,降低了编程成本,提高了编程安全性,同时兼顾了性能,执行速度还挺快。
JVM运行在操作系统之上,解释执行字节码文件。是Java语言和操作系统的桥梁。
Java语言和JVM规范
参考资料首推Oracle官网Java语言和虚拟机规范,英文不太友好,推荐安装插件(谷歌翻译、必应翻译)配合观看。
- 所有版本语言和虚拟机规范:https://docs.oracle.com/javase/specs/index.html
- Java11虚拟机规范:https://docs.oracle.com/javase/specs/jvms/se11/html/index.html
- Java8虚拟机规范:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
JVM=JVM规范+JVM具体实现
- JVM规范有很多个版本,目前不做特别指定,就是指JDK8版本JVM,如果有追新的需要,可再关注下JDK11的JVM
- JVM的具体实现也有很多个版本,目前不做特别指定,就是指Hotspot VM。
本文以Oracle JDK 8 的Hotspot VM为主,学习。
JVM的整体结构
JVM=类加载器+运行时+执行引擎+本地方法库类加载子系统:将class文件加载到内存
- 运行时数据区:JVM进程运行时数据存储区域,各种数据结构
- 多线程共享“方法区”和“堆”
- 线程内部区域:栈,本地方法区,程序计数器
- 执行引擎:解释执行字节码文件
- 本地方法库:调用操作系统暴露的本地执行接口
Java语言执行流程
所有的高级语言,执行流程都是: 高级语言->汇编语言->机器指令->CPU执行
Java这种高级语言的执行流程:
.java文件经过编译器javac的编译后,生成字节码文件.class,由JVM解释执行或即时编译为机器指令,然后调用操作系统执行。
JVM的架构模型
一般有两周架构,“基于栈的指令集架构”和“基于寄存器的指令集架构”,Java使用基于栈的指令集架构实现JVM。
两种架构的区别:
基于栈的指令集架构:
- 设计和实现简单,较适用于资源受限的系统(如嵌入式系统)
- 不需要硬件支持,可移植性好
- 缺点是比基于寄存器的指令集架构性能差,运行慢
基于寄存器的指令集架构:
- 指令集依赖硬件,可移植性差
- 性能优秀,执行性更高
Java之父和Sun公司当年选择了“基于栈的指令集架构”并延续至今。
JVM的生命周期
- 启动: 由类加载器启动一个JVM进程
- 执行:执行Java程序,一个程序是一个JVM进程
- 退出:Java程序执行完成后JVM退出