写点什么

【死磕 JVM】JVM 快速入门之前戏篇

用户头像
牧小农
关注
发布于: 2021 年 02 月 24 日
【死磕JVM】JVM快速入门之前戏篇

简介

Java 是一门可以跨平台的语言,但是 Java 本身是不可以实现跨平台的,需要 JVM 实现跨平台。javac 编译好后的 class 文件,在 Windows、Linux、Mac 等系统上,只要该系统安装对应的 Java 虚拟机,class 文件都可以运行。达到 ”一次编译,到处运行” 的效果。


什么是 JVM

JVM 是可以运行在 Java 代码的虚拟的计算机,既然是虚拟的计算机,当然也包含自己的 CPU、字节码指令集、寄存器、栈、垃圾回收、堆和存储方法域,我们可以理解成 JVM 自己就是一套操作系统。


Java 从编译到执行

Virtual Machine 是物理机器的软件实现。Java 是用在 VM 上运行的 WORA(Write Once Run Anywhere)概念而开发的。编译器将 Java 文件编译为 Java .class 文件,然后将.class 文件输入到 JVM 中,JVM 会加载并执行类文件,如下图所示:



1. 编译

对于 Java 代码来说,是对于一个 java 类的编译,利用 java 编译器(javac.exe)将源码编译成能够被 JVM 的类加载器加载的.class 文件(字节码),字节码不是机器码,是一个中间代码,与平台无关。java 编译一个类的时候,如果这个类所依赖的类还没有被编译,编译器就会先编译这个被依赖的类,然后引用,如果 java 编译器在指定的目录下找不到该类所依赖的类的 .class 文件或者 .java 源文件,就会报 ``"Cant found sysbol"``的异常错误。


编译后的字节码文件格式主要分为两部分:常量池和方法字节码。

  • 常量池记录的是代码出现过的(常量、类名、成员变量等)以及符号引用(类引用、方法引用,成员变量引用等);

  • 方法字节码中放的是各个方法的字节码。


2. 执行

java 类执行的过程大概分为两个步骤:

  1. 类的加载

  2. 类的执行


需要说明的一点的是:JVM 主要在程序第一次运行时主动使用类的时候,才会立即去加载。换言之,JVM 并不是在运行时就会把所有使用到的类都加载到内存中,而是用到,不得不加载的时候,才加载进来,而且只加载一次。


从跨平台的语言到跨语言的平台

目前有一百多种语言可以跑在 Java 虚拟机上....


1、Java 是跨平台的语言

意思是说程序员写代码的时候只需要写一次代码,javac 编译也只编译一次,但是可以在 windows 上运行,也可以把打好的包放到 linux 或者 macos 上运行。


2、jvm 是跨语言的平台

任何语言只要使用提供的编译器编译相应的语言,通过 jvm 就可以运行了

2、jvm 与 Java 无关

任何语言只要你能编译成 class 就可以编译在 JVM 上



JVM

JVM 是一种规范

(1)虚拟机是一种抽象的计算机,通过从实际的计算机中仿真模拟各种计算机功能来实现的。JAVA 虚拟机规范是一种对 JAVA 虚拟机实现的规范要求,是由 oracle 制定的,而我们平时常说的 JAVA 虚拟机一般是指的一种具体的 JAVA 虚拟机规范的实现。比如我们最经常使用的 JAVA 虚拟机 hotspot,其实 JAVA 虚拟机还有很多种实现,甚至如果你对 JAVA 虚拟机规范有了深入的了解而且对此有兴趣的话,可以写一个自己的 JAVA 虚拟机,当然这其中的难度不难想象。Java 虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 Java 虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。


(2)JVM 是 Java 程序运行的环境,同时是一个操作系统的一个应用程序进程,因此它有自己的生命周期,也有己的代码和数据空间。


(3)JVM 体系主要是两个 JVM 的内部体系结构分为三个子系统和两大组件,分别是: 类装载(ClassLoader)子系统、执行引擎子系统和 GC 子系统 组件是内存运行数据区域和本地接口。


常见的 JVM 实现

一、Hotspot

HotSpot VM,它是 Sun JDK 和 OpenJDK 中所带的虚拟机,也是目前使用范围最广的 Java 虚拟机。

但不一定所有人都知道的是,这个目前看起来“血统纯正”的虚拟机在最初并非由 Sun 公司开发,而是由一家名为“Longview Technologies”的小公司设计的;

甚至这个虚拟机最初并非是为 Java 语言而开发的,它来源于 Strongtalk VM,

而这款虚拟机中相当多的技术又是来源于一款支持 Self 语言实现“达到 C 语言 50%以上的执行效率”的目标而设计的虚拟机,

Sun 公司注意到了这款虚拟机在 JIT 编译上有许多优秀的理念和实际效果,在 1997 年收购了 Longview Technologies 公司,从而获得了 HotSpot VM。


HotSpot VM 既继承了 Sun 之前两款商用虚拟机的优点(如前面提到的准确式内存管理),也有许多自己新的技术优势,

如它名称中的 HotSpot 指的就是它的热点代码探测技术(其实两个 VM 基本上是同时期的独立产品,HotSpot 还稍早一些,HotSpot 一开始就是准确式 GC,

而 Exact VM 之中也有与 HotSpot 几乎一样的热点探测。

为了 Exact VM 和 HotSpot VM 哪个成为 Sun 主要支持的 VM 产品,在 Sun 公司内部还有过争论,HotSpot 打败 Exact 并不能算技术上的胜利),

HotSpot VM 的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知 JIT 编译器以方法为单位进行编译。

如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准编译和 OSR(栈上替换)编译动作。

通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,

即时编译的时间压力也相对减小,这样有助于引入更多的代码优化技术,输出质量更高的本地代码。


在 2006 年的 JavaOne 大会上,Sun 公司宣布最终会把 Java 开源,并在随后的一年,陆续将 JDK 的各个部分(其中当然也包括了 HotSpot VM)在 GPL 协议下公开了源码,

并在此基础上建立了 OpenJDK。这样,HotSpot VM 便成为了 Sun JDK 和 OpenJDK 两个实现极度接近的 JDK 项目的共同虚拟机。


在 2008 年和 2009 年,Oracle 公司分别收购了 BEA 公司和 Sun 公司,这样 Oracle 就同时拥有了两款优秀的 Java 虚拟机:JRockit VM 和 HotSpot VM。

Oracle 公司宣布在不久的将来(大约应在发布 JDK 8 的时候)会完成这两款虚拟机的整合工作,使之优势互补,所以我们现在使用的虚拟机应该就是整合之后的虚拟机。

整合的方式大致上是在 HotSpot 的基础上,移植 JRockit 的优秀特性,譬如使用 JRockit 的垃圾回收器与 MissionControl 服务,使用 HotSpot 的 JIT 编译器与混合的运行时系统。


查看 JVM,我们只需要使用 ``java -version``就可以查看了


二、Jrockit

jrockit 前身是 BA jrockit,后被 oracle 收购,并免费发布,但并不开源。

jrockit 可以看做是兼容标准的 JDK 基础上的 JVM,同原有的 JVM 相比,jrockit 声称在速度上有显著的提高(甚至超过 70%),jrockit 在速度上的优势使其应用在时间敏感的领域内,如军事,电信,控制等,这也得益于其针对不同处理器架构所做的优化,曾经号称是世界上最快的 JVM


三、J9

J9 是一个 IBM 推出的 Java 虚拟机和类库,J9 在 IBM 的从移动设备到企业解决方案中广泛的被使用


四、Microsoft VM

来自于微软的 JVM


五、TaobaoVM

hotspot 深度定制版,除了在性能优化方面下足了功夫,TaobaoVM 还在 HotSpot 的基础之上大幅度扩充了一些特定的增强实现。比如创新的 GCIH(GC invisible heap)技术实现 off-heap,这样一来就可以将生命周期较长的 Java 对象从 heap 中移至 heap 之外,并且 GC 不能管理 GCIH 内部的 Java 对象,这样做最大的好处就是降低了 GC 的回收平率以及提升了 GC 的回收效率,并且 GCIH 中的对象还能够在多个 Java 虚拟机进程中实现共享。其他扩充技术还有利用 PMU hardware 的 Java profiling tool 和诊断协助功能等。


据说淘宝里面大概有十个人能够手写 TaobaoVM,都是 P9 P10 级别的


六、LiquidVM

直接针对于硬件


七、azul zing

最新垃圾回收的业界标杆,性能极高,但是这个是收费的,并且只有土豪才用的起。


官网:www.azul.com


JDK JRE JVM


JVM : 英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。


JRE : 英文名称(Java Runtime Environment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。


JDK : 英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。


显然,这三者的关系是:一层层的嵌套关系。 JDK>JRE>JVM


为什么我们的电脑在装完 jdk 后会有两个版本的 jre?

没有联系。甚至准确的来说,它俩是一样的,无论是用哪一个都是可以的。只是很多人习惯将会单独安装另一个 jre,虽然单独安装的 jre 也并没有被使用,原因可能就是刚开始大家都不清楚 jdk 和 jre 之间的关系,所以就默认的都安装上了。


小结


今天的 JVM 知识点就讲完了,有疑问的小伙伴可以留言或评论


怕什么真理无穷,进一步有进一步的欢喜,我是牧小农,大家加油!!!


发布于: 2021 年 02 月 24 日阅读数: 39
用户头像

牧小农

关注

业精于勤,荒于嬉;行成于思,毁于随! 2019.02.13 加入

业精于勤荒于嬉,行成于思毁于随

评论

发布
暂无评论
【死磕JVM】JVM快速入门之前戏篇