虚拟机(Virtual Machine), 即一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。
无论是系统虚拟机还是程序虚拟机,在上面运行的软件都被限制于虚拟机提供的资源中。
Java虚拟机是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必由Java语言编译而成。JVM平台的各种语言可以共享Java虚拟机带来的跨平台性、优秀的垃圾回器,以及可靠的即时编译器。
Java技术的核心就是Java虚拟机(JVM,Java Virtual Machine),因为所有的Java程序都运行在Java虚拟机内部。
Java虚拟机的作用:
Java虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条Java指令,Java虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。
Java虚拟机的特点:
JVM是运行在操作系统上的 ,它与硬件没有直接的交互:
JVM所在的位置:
JDK、JRE与JVM
JDK: Java Development Kit 的简称,java 开发工具包,是Sun Microsystems针对Java开发员的产品,提供了 java 的开发环境和运行环境,JDK中包含JRE,在JDK的安装目录中可以找到一个jre的目录。
JRE: Java Runtime Environment 的简称,是运行基于Java语言编写的程序所不可缺少的运行环境。通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。在jre文件中有bin和lib文件夹,我们可以认为bin文件夹对应的就是JVM,而lib则对应JVM工作所需要的类库。
JVM: java virtual machine简称,是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为 .class 的类文件,这种类文件可以在虚拟机上执行。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
需要运行 java 程序,只需安装 JRE 就可以了
需要编写 java 程序,需要安装 JDK
Java代码执行流程:
-> java源程序通过编译器(javac.exe)对javac文件(.java)进行编译
–> 生成字节码文件(.class)
—> 类加载器把字节码加载到内存,放入运行时数据区的方法区内
-----> 执行引擎读取字节码并逐段执行
------> 解释执行(对字节码指令进行逐行的解释)编译执行(将热点代码编译成机器指令)
-------> 在操作系统(Windows,Linux等)上执行
什么是字节码文件?
我们平时说的Java字节码,指的是Java语言编译成的字节码。准确的说任何能在jvm平台上执行的字节码格式都是一样的,都被统称为:jvm字节码
不同的编译器,可以编译出相同的字节码文件,字节码文件也可以在不同的JVM上运行。
Java虚拟机与Java语言并没有必然的联系,它只是与特定的二进制文件格式(class文件)格式所关联,class文件包含了Java虚拟机指令集(字节码、Bytecodes)和符号表,还有一些其他辅助信息。
随着Java7的正式发布,Java虚拟机的设计者们通过JSR-292规范基本实现了Java虚拟机平台上运行非Java语言编写程序。
Java虚拟机根本不关心运行在其内部的程序到底是使用何种编程语言编写的,它只关心“字节码“文件。也就是说Java虚拟机拥有语言无关性,并不会单纯地与Java语言”终身绑定“,只要其他编程语言的编译结果满足并包含Java虚拟机的内部指令集、符号表以及其他的辅助信息,他就是一个有效的字节码文件,就能够被虚拟机所识别并装载运行。
多语言混合编程:
Java平台上的多种语言混合编程正成为主流,通过特定领域的语言去理解特定领域的问题是当前软件开发应对日趋复杂的项目需求的一个方向。
在项目开发中,每层的实现可以使用不同的语言,接口对每一层开发者都是透明的,各种语言之间的交互不存在任何困难,就像使用自己语言的原生API一样方便,因为它们最终都运行在一个虚拟机之上。
、
HotSpot VM是目前市面上高性能虚拟机的代表作之一,它采用解释器与即时编译器并存的结构。
JVM的由以下几部分组成:
类加载器三部分: 加载(Loading)、链接(Linking)、初始化(Initialization)
运行时数据区五部分: 方法区/元空间(Method Area)、堆区域(Heap Area)、栈区域(Stack Area)、程序计数器(PC Registers)、本机方法栈(Native Method statcks)
执行引擎三部分: 解释器(Interpreter),及时编译器(JIT Compiler),垃圾回收器(Garbage Collection)
Java编译器输入的指令流基本上是一种基本栈的指令集架构,另一种指令集架构则是基于寄存器的指令集架构。
基于栈式架构的特点:
基于寄存器架构的特点:
总结: 由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。栈相对于寄存器:跨平台、指令集小、编译器容易实现、指令多;但是执行性能比寄存器差,实现同样的功能需要更多的指令。
举例:执行2+3操作
基于栈的计算流程(以Java虚拟机为例):
iconst_2 //常量2入栈
istore_1
iconst_3 // 常量3入栈
istore_2
iload_1
iload_2
iadd //常量2/3出栈,执行相加
istore_0 // 结果5入栈
而基于寄存器的计算流程:
mov eax,2 //将eax寄存器的值设为1
add eax,3 //使eax寄存器的值加3
虚拟机的启动:
Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。
虚拟机的执行:
一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序。
程序开始执行时他才运行,程序结束时他就停止。
执行一个所谓的Java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程。
虚拟机的退出:
Sun Classic VM: 早在1996年Java1.0版本的时候,由Sun公司发布,是世界上第一款商用Java虚拟机,JDK1.4时完全被淘汰。这款虚拟机内部只提供解释器。
Exact VM: 为了解决上一个虚拟机问题,jdk1.2时,sun提供了此虚拟机。
HotSpot VM(重点)
HotSpot历史:
最初由一家名为“Longview Technologies”的小公司设计。1997年,此公司被sun收购;2009年,Sun公司被甲骨文收购。
JDK1.3时,HotSpot VM成为默认虚拟机
目前Hotspot占有绝对的市场地位,称霸武林:
名称中的HotSpot指的就是它的热点代码探测技术:
JRockit: 专注于服务器端应用,它可以不太关注程序启动速度,因此JRockit内部不包含解析器实现,全部代码都靠即时编译器编译后执行。
大量的行业基准测试显示,JRockit JVM是世界上最快的JVM:使用JRockit产品,客户已经体验到了显著的性能提高(一些超过了70%)和硬件成本的减少(达50%)。
优势:全面的Java运行时解决方案组合
2008年,JRockit被oracle收购。oracle表达了整合两大优秀虚拟机的工作,大致在JDK8中完成。整合的方式是在HotSpot的基础上,移植JRockit的优秀特性。
IBM的J9: IBM的J9,全称IBM Technology for Java Virtual Machine,简称IT4J,内部代号:J9
市场定位与HotSpot接近,服务器端、桌面应用、嵌入式等多用途VM广泛用于IBM的各种Java产品。目前,有影响力的三大商用虚拟机之一,也号称是世界上最快的Java虚拟机。
2017年左右,IBM发布了开源J9VM,命名为openJ9,交给EClipse基金会管理,也称为Eclipse OpenJ9。
KVM和CDC / CLDC Hotspot: Oracle在Java ME产品线上的两款虚拟机为:CDC/CLDC HotSpot Implementation VM KVM(Kilobyte)是CLDC-HI早期产品目前移动领域地位尴尬,智能机被Angroid和ioS二分天下。
KVM简单、轻量、高度可移植,面向更低端的设备上还维持自己的一片市场:
Azul VM: 前面三大“高性能Java虚拟机”使用在通用硬件平台上,这里Azu1VW和BEALiquid VM是与特定硬件平台绑定、软硬件配合的专有虚拟机:高性能Java虚拟机中的战斗机。
Azul VM是Azu1Systems公司在HotSpot基础上进行大量改进,运行于Azul Systems公司的专有硬件Vega系统上的ava虚拟机。
每个Azu1VM实例都可以管理至少数十个CPU和数百GB内存的硬件资源,并提供在巨大内存范围内实现可控的GC时间的垃圾收集器、专有硬件优化的线程调度等优秀特性。
2010年,AzulSystems公司开始从硬件转向软件,发布了自己的zing JVM,可以在通用x86平台上提供接近于Vega系统的特性。
Liquid VM: 高性能Java虚拟机中的战斗机。由BEA公司开发,直接运行在自家Hypervisor系统上
Liquid VM即是现在的JRockit VE(Virtual Edition),它不需要操作系统的支持,或者说它自己本身实现了一个专用操作系统的必要功能,如线程调度、文件系统、网络支持等。
随着JRockit虚拟机终止开发,Liquid vM项目也停止了。
Apache Marmony: Apache也曾经推出过与JDK1.5和JDK1.6兼容的Java运行平台Apache Harmony。
它是IElf和Inte1联合开发的开源JVM,受到同样开源的openJDK的压制,Sun坚决不让Harmony获得JCP认证,最终于2011年退役,IBM转而参与OpenJDK
虽然目前并没有Apache Harmony被大规模商用的案例,但是它的Java类库代码吸纳进了Android SDK。
Micorsoft JVM: 微软为了在IE3浏览器中支持Java Applets,开发了Microsoft JVM。该虚拟机只能在window平台下运行。但确是当时Windows下性能最好的Java VM。
1997年,sun以侵犯商标、不正当竞争罪名指控微软成功,赔了sun很多钱。微软windowsXPSP3中抹掉了其VM。现在windows上安装的jdk都是HotSpot。
Taobao JVM: 由AliJVM团队发布。阿里,国内使用Java最强大的公司,覆盖云计算、金融、物流、电商等众多领域,需要解决高并发、高可用、分布式的复合问题。有大量的开源产品。
基于openJDK开发了自己的定制版本AlibabaJDK,简称AJDK。是整个阿里Java体系的基石。基于openJDK Hotspot VM发布的国内第一个优化、深度定制且开源的高性能服务器版Java虚拟机。
taobao vm应用在阿里产品上性能高**,硬件严重依赖inte1的cpu,损失了兼容性,但提高了性能**,目前已经在淘宝、天猫上线,把oracle官方JvM版本全部替换了。
Dalvik VM: 谷歌开发的,应用于Android系统,并在Android2.2中提供了JIT,发展迅猛。
Dalvik VM只能称作虚拟机,而不能称作“Java虚拟机”,它没有遵循 Java虚拟机规范,不能直接执行Java的Class文件。
该虚拟机基于寄存器架构,不是jvm的栈架构,执行的是编译以后的dex(Dalvik Executable)文件。执行效率比较高。
Android 5.0使用支持提前编译(Ahead of Time Compilation,AoT)的ART VM替换Dalvik VM。
Graal VM: 2018年4月,Oracle Labs公开了GraalvM,号称 “Run Programs Faster Anywhere”,勃勃野心。与1995年java的”write once,run anywhere"遥相呼应。
GraalVM在HotSpot VM基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用。语言包括:Java、Scala、Groovy、Kotlin;C、C++、Javascript、Ruby、Python、R等,同时支持不同语言中混用对方的接口和对象,支持这些语言使用已经编写好的本地库文件。
工作原理是将这些语言的源代码或源代码编译后的中间格式,通过解释器转换为能被Graal VM接受的中间表示。Graal VM提供Truffle工具集快速构建面向一种新语言的解释器。在运行时还能进行即时编译优化,获得比原生编译器更优秀的执行效率。