Java虚拟机-第1章笔记-走近Java虚拟机
2022-01-20 17:14:21 25 举报
AI智能生成
Java虚拟机-第1章笔记-走近Java虚拟机
作者其他创作
大纲/内容
1.1 概述
Java不仅仅是一门编程语言,它还是一个由一系列计算机软件和规范组成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于嵌入式系统、移动终端、企业服务器、大型机等多种场合
Java的优点
它拥有一门结构严谨、面向对象的编程语言;
它摆脱了硬件平台的束缚,实现了“一次编写,到处运行”的理想;
它提供了一种相对安全的内存管理和访问机制,避免了绝大部分内存泄漏和指针越界问题;
它实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的增长而获得更高的性能;
它有一套完善的应用程序接口,还有无数来自商业机构和开源社区的第三方类库来帮助用户实现各种各样的功能;
1.2 Java技术体系
Java技术体系组成部分
Java程序设计语言
各种硬件平台上的Java虚拟机实现
Class文件格式
Java类库API
来自商业机构和开源社区的第三方Java类库
JDK(Java Development Kit),JDK是用于支持Java程序开发的最小环境
Java程序设计语言
Java类库
Java虚拟机
JRE(Java Runtime Environment),JRE是支持Java程序运行的标准环境
Java类库API中的Java SE API子集
Java虚拟机
Java技术体系所包括的内容
图片
Java技术体系的四条主要的产品线
Java Card:支持Java小程序(Applets)运行在小内存设备(如智能卡)上的平台。
Java ME(Micro Edition):支持Java程序运行在移动终端(手机、PDA)上的平台,对Java API有所精简,并加入了移动终端的针对性支持,这条产品线在JDK 6以前被称为J2ME。现在在智能手机上非常流行的、主要使用Java语言开发程序的Android并不属于Java ME。
Java SE(Standard Edition):支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API,这条产品线在JDK 6以前被称为J2SE。
Java EE(Enterprise Edition):支持使用多层架构的企业应用(如ERP、MIS、CRM应用)的Java平台,除了提供Java SE API外,还对其做了大量有针对性的扩充 ,并提供了相关的部署支持,这条产品线在JDK 6以前被称为J2EE,在JDK 10以后被Oracle放弃,捐献给Eclipse基金会管理,此后被称为Jakarta EE。
1.3 Java发展史
图片
1.4 Java虚拟机家族
1. 虚拟机始祖:Sun Classic/Exact VM
Sun Classic 世界上第一款商用Java虚拟机
Sun Classic 只能使用纯解释器方式来执行Java代码,如果要使用即时编译器那就必须进行外挂,但是假如外挂了即时编译器的话,即时编译器就会完全接管虚拟机的执行系统,解释器便不能再工作了。
Exact VM的虚拟机,它的编译执行系统已经具备现代高性能虚拟机雏形,如热点探测、两级即时编译器、编译器与解释器混合工作模式等。
Exact VM因它使用准确式内存管理(Exact Memory Management,也可以叫Non-Con-servative/Accurate Memory Management)而得名。准确式内存管理是指虚拟机可以知道内存中某个位置的数据具体是什么类型。
2. 武林盟主:HotSpot VM
目前使用范围最广的Java虚拟机。
HotSpot虚拟机的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知即时编译器以方法为单位进行编译。如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准即时编译和栈上替换编译(On-Stack Replacement,OSR)行为。通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更复杂的代码优化技术,输出质量更高的本地代码。
3. 小家碧玉:Mobile/Embedded VM
Java SE Embedded里带的Java虚拟机当然还是HotSpot,但这是为了适应嵌入式环境专门定制裁剪的版本,尽可能在支持完整的Java SE功能的前提下向着减少内存消耗的方向优化,譬如只留下了客户端编译器(C1),去掉了服务端编译器(C2);只保留Serial/Serial Old垃圾收集器,去掉了其他收集器等。
4. 天下第二:BEA JRockit/IBM J9 VM
IBM J9虚拟机一款在设计上全面考虑服务端、桌面应用,再到嵌入式的多用途虚拟机。
IBM J9虚拟机的职责分离与模块化做得比HotSpot更优秀,由J9虚拟机中抽象封装出来的核心组件库(包括垃圾收集器、即时编译器、诊断监控子系统等)就单独构成了IBM OMR项目。
5. 软硬合璧:BEA Liquid VM/Azul VM
与特定硬件平台绑定、软硬件配合工作的专有虚拟机,往往能够实现更高的执行性能,或提供某些特殊的功能特性。
在要求低延迟、快速预热等场景中,Zing VM都要比HotSpot表现得更好。Zing的PGC、C4收集器可以轻易支持TB级别的Java堆内存,而且保证暂停时间仍然可以维持在不超过10毫秒的范围里,HotSpot要一直到JDK 11和JDK 12的ZGC及Shenandoah收集器才达到了相同的目标,而且目前效果仍然远不如C4。
Zing能让普通用户无须了解垃圾收集等底层调优,就可以使得Java应用享有低延迟、快速预热、易于监控的功能。
6. 挑战者:Apache Harmony/Google Android Dalvik VM
7. 没有成功,但并非失败:Microsoft JVM及其他
8. 百家争鸣
1.5 展望Java技术的未来
1. 无语言倾向
Java“天下第一”的底气不在于语法多么先进好用,而是来自它庞大的用户群和极其成熟的软件生态,这在朝夕之间难以撼动。
互联网之于JavaScript、人工智能之于Python,微服务风潮之于Golang等
Graal-VM可以无额外开销地混合使用这些编程语言,支持不同语言中混用对方的接口和对象,也能够支持这些语言使用已经编写好的本地库文件。
Graal-VM的基本工作原理是将这些语言的源代码(例如JavaScript)或源代码编译后的中间格式(例如LLVM字节码)通过解释器转换为能被Graal VM接受的中间表示(Intermediate Representation,IR),譬如设计一个解释器专门对LLVM输出的字节码进行转换来支持C和C++语言,这个过程称为程序特化(Specialized,也常被称为Partial Evaluation)。
Graal-VM提供了Truffle工具集来快速构建面向一种新语言的解释器,并用它构建了一个称为Sulong的高性能LLVM字节码解释器。
Graal-VM才是真正意义上与物理计算机相对应的高级语言虚拟机,理由是它与物理硬件的指令集一样,做到了只与机器特性相关而不与某种高级语言特性相关。
对于一些本来就不以速度见长的语言运行环境,由于Graal-VM本身能够对输入的中间表示进行自动优化,在运行时还能进行即时编译优化,因此使用Graal-VM实现往往能够获得比原生编译器更优秀的执行效率
2. 新一代即时编译器
对需要长时间运行的应用来说,由于经过充分预热,热点代码会被HotSpot的探测机制准确定位捕获,并将其编译为物理硬件可直接执行的机器码,在这类应用中Java的运行效率很大程度上取决于即时编译器所输出的代码质量。
HotSpot虚拟机中含有两个即时编译器,分别是编译耗时短但输出代码优化程度较低的客户端编译器(简称为C1)以及编译耗时长但输出代码优化质量也更高的服务端编译器(简称为C2),通常它们会在分层编译机制下与解释器互相配合来共同构成HotSpot虚拟机的执行子系统
3. 向Native迈进
提前编译是相对于即时编译的概念,提前编译能带来的最大好处是Java虚拟机加载这些已经预编译成二进制库之后就能够直接调用,而无须再等待即时编译器在运行时将其编译成二进制机器码。理论上,提前编译可以减少即时编译带来的预热时间,减少Java应用长期给人带来的“第一次运行慢”的不良体验,可以放心地进行很多全程序的分析行为,可以使用时间压力更大的优化措施 。
但是提前编译的坏处也很明显,它破坏了Java“一次编写,到处运行”的承诺,必须为每个不同的硬件、操作系统去编译对应的发行包;也显著降低了Java链接过程的动态性,必须要求加载的代码在编译期就是全部已知的,而不能在运行期才确定,否则就只能舍弃掉已经提前编译好的版本,退回到原来的即时编译执行状态。
4. 灵活的胖子
HotSpot开发团队正在持续地重构着HotSpot的架构,让它具有模块化的能力和足够的开放性。
JDK 1.4时代及之前曾开放过Java虚拟机信息监控接口(Java Virtual Machine Profiler Interface,JVMPI)与Java虚拟机调试接口(Java Virtual Machine Debug Interface,JVMDI)供运维和性能监控、IDE等外部工具使用。
JDK 5时期,又抽象出了层次更高的Java虚拟机工具接口(Java Virtual Machine Tool Interface,JVMTI)来为所有Java虚拟机相关的工具提供本地编程接口集合。
JDK 6时期,JVMTI就完全整合代替了JVMPI和JVMDI的作用。
JDK 9时期,HotSpot虚拟机开放了Java语言级别的编译器接口 (Java Virtual Machine Compiler Interface,JVMCI),使得在Java虚拟机外部增加、替换即时编译器成为可能,这个改进实现起来并不费劲,但比起之前JVMPI、JVMDI和JVMTI却是更深层次的开放,它为不侵入HotSpot代码而增加或修改HotSpot虚拟机的固有功能逻辑提供了可行性。Graal编译器就是通过这个接口植入到HotSpot之中。
JDK 10时期,HotSpot又重构了Java虚拟机的垃圾收集器接口(Java Virtual Machine Compiler Interface),统一了其内部各款垃圾收集器的公共行为。
5. 语言语法持续增强
1.6 实战:自己编译JDK
0. 概述
想要窥探Java虚拟机内部的实现原理,最直接的一条路径就是编译一套自己的JDK,通过阅读和跟踪调试JDK源码来了解Java技术体系的运作,虽然这样门槛会比阅读资料更高一点,但肯定也会比阅读各种文章、书籍来得更加贴近本质。
此外,Java类库里的很多底层方法都是Native的,在了解这些方法的运作过程,或对JDK进行Hack(根据需要进行定制微调)的时候,都需要有能自行编译、调试虚拟机代码的能力。
1. 获取源码
2. 系统需求
3. 构建编译环境
4. 进行编译
5. 在IDE工具中进行源码调试
如果导图对您有用,请在右上角给点个赞吧
0 条评论
下一页