Java 跨平台的意义在于一次编译,处处运行,这里 JVM 功不可没。比如在 Maven 仓库下载的 jar 包就可以到处运行,不需要在每个平台上再编译一次。
我们来概括 JVM 与操作系统之间的关系:
JVM 上承开发语言,下接操作系统,它的中间接口就是字节码。
JVM、JRE、JDK 的关系通过上面的学习,我们了解到 JVM 是 Java 程序能够运行的核心。但是我们要知道,JVM 自己什么也干不了,你需要给它提供原料(.class 文件)。俗话说:巧妇难为无米之炊。JVM 功能虽然强大,但还是需要为它提供 .class 文件。
但是仅靠 JVM 是无法完成一次编译,到处运行的。它需要一个基本的类库,比如怎么操作文件、怎么连接网络、怎么教你出拳(小李已疯)等。而 Java 体系会一次性将 JVM 运行所需的类库都传递给它。JVM 标准加上基本类库就组成了 Java 的运行环境,就是 JRE (Java Runtime Enviroment)
JVM + 基本类库 = JRE
那 JDK 又是什么呢?
JDK 全称 Java Development Kit,Kit 是装备的意思。所以 JDK 不仅包含 JRE,还有一些小工具,比如 javac、java、jar等。
JRE + javac/java/jar 等指令工具 = JDK
JVM、JRE、JDK 它们三者之间的关系,可以用一个包含关系表示。
JDK > JRE > JVM
Java 虚拟机规范和 Java 语言规范的关系从广义上来讲,JVM 是一种规范,它是最为官方、准确的文档;狭义上来讲,由于我们使用 Hotspot 更多一些,所以我们在谈到这个概念时,会将他们等同起来。
如果再加我们平常使用的 Java 语言,可以得到下面一张图。
左边是 Java 虚拟机规范,为字节码的解析提供一个环境。右边是 Java 语法规范,比如 switch、for、泛型、lambda 等相关的程序,最终都会编译成字节码。而字节码是链接左右两部分的桥梁。
如果 .class 文件的规格是不变的,这两部分是可以独立进行优化的。But 没有如果,现在都已经到 Java 13 了,为了支持更多的特性,肯定会增加一些字节码指令。
此刻优秀的小李提出了一个让人深思的问题:
如果我不学习 JVM,会影响我写 Java 代码么?
理论上,这两者没有必然的联系。他们之间通过 .class 文件进行交互,即使你不了解 JVM,也能够写大多数的 Java 代码。就像你是写 C++ 代码一样,并不需要特别深入的了解操作系统的底层是如何实现的。
那我还学个锤子!瞬间关了该页面。
客官别走,还有但是没说呢。
但是,如果你想要写一些比较精巧、效率比较高的代码,就需要了解一些执行层面的知识了。了解 JVM,主要用在调优以及故障排查上面,你会对运行中的各种资源分配,有一个比较全面的掌控。(是不是内心还有点小期待呢!)
Java 代码到底是如何运行起来的最后,我们简单看一下 Java 程序的执行过程,了解下它到底是如何运行起来的。
这里的 Java 程序是文本格式的。比如下面这段 HelloXiaoli.java,它遵循的就是 Java 语言规范。其中,我们调用的 System.out 等模块,就是 JRE 提供的类库。
通过 JDK 的工具 javac 进行编译后,就会产生 HelloWorld 的字节码。
1javac HelloXiaoli.java