1. 为什么 Java 需要运行时环境

1.1. Java 程序的启动方式

  • IDE中启动,比如:Eclipse、IntelliJ IDEA
  • 构建为 jar,通过命令行的方式启动,比如:java -jar application.jar
  • 使用构建工具(如:Gradle、Maven)启动,比如 SpringBoot 应用启动:gradle bootRun、mvn spring-boot:run

1.2. JRE 是什么

在这里引用极客时间课程Java核心技术面试精讲中的一段话

我们日常会接触到 JRE(Java Runtime Environment) 或者 JDK(Java Development Kit)JRE,也就是 Java 运行时环境,仅包含运行 Java 程序的必须组件,包括 Java 虚拟机以及 Java 核心类库等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。

1.3. 为什么需要运行时环境

不是有这么一句话么,计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。话说回来,Java 代码运行之所以需要运行时环境,主要是由于以下几个方面的原因:

  • Java 语言语法非常复杂,抽象程度高,直接在硬件上运行这种复杂的程序并不现实(并不是不可以,但是这样造成与相应硬件的强耦合,且不便于抽象和复杂语法的实现。),所以需要在运行之前进行一番转换。

  • 实现平台无关性、做到 “Write once, run anywhere”,获得跨平台的能力。这样便需要一个中间层进行解耦,达到上层统一编码、下层跨越平台、中间实现兼容(所以,Java 语言的跨平台特性是由 Java 运行时环境实现的。也就是在不同平台皆有与之相对应的 Java 运行时环境,实现相同定义、不同实现。这样的思想是不是很熟悉,当然,这仅是我的理解)。

  • 提供托管环境(Managed Runtime),该托管环境可以代替我们处理一些通用的、容易出错的、高难度的行为,比如自动内存管理、垃圾回收、安全权限动态检测等。

2. Java 代码在虚拟机中是怎样运行的

2.1. 虚拟机视角

执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中,加载后的 Java 类会被存放到方法区中。实际运行时,虚拟机会执行方法区内的代码(需要将字节码翻译为机器码,在 HotSpot 实现中,有解释执行和即时编译两种)。

下图为 Java虚拟机的整体内存结构图(并不细致),从图中可以看到,Java 虚拟机将栈细分为 Java 方法栈(Java 虚拟机栈)和面向本地方法(用 C++ 写的 native 方法)的本地方法栈,以及存放各个线程的 PC 寄存器(每个线程都有自己的 PC 寄存器,也是该线程启动时创建的)。

深入Java虚拟机第一讲——Java虚拟机内存模型

在运行过程中,每当调用进入一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧(并入栈),用于存放局部变量以及字节码的操作数。这个栈帧的大小是提前计算好的(编译为字节码的过程中计算的),而且 Java 虚拟机不要求栈帧在内存空间里连续分布。当退出当前执行的方法是,不管是正常返回还是异常返回,Java 虚拟机均会将该方法对应的栈帧弹出(出栈并舍弃)。

2.2. 硬件视角

Java 字节码无法在硬件上直接执行,因此,Java 虚拟机需要将字节码翻译成机器码。在 HotSpot 里面,上述翻译过程有两种形式:第一种是解释执行,即逐条将字节码翻译成机器码执行;第二种是即时编译(JIT),即将一个方法中包含的所有字节编译成机器码后再执行。(编译执行与编译执行的区别可类比为同声传译与放录音,同声传译每一次都需要完整的执行,但是不需要过多等待;而放录音则是一劳永逸,但是存在第一次的录音的过程)

解释执行的优势在于无需等待编译,而即时编译的优势在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。

3. 作业解析

–> 待办

4. 总结

Java 需要运行时环境支持的原因主要有:

  • 语法复杂、高度抽象
  • 实现跨平台
  • 提供托管环境

Java 虚拟机将运行时内存区域划分为五个部分,分别为方法区、堆、PC 寄存器、Java 方法栈和本地方法栈。Java 程序编译而成的 class 文件,需要先加载至方法区中,方能在 Java 虚拟机中运行。

5. 参考

6. 说明

我不是在卖课

本文大部分内容来源于极客时间以及网络博文节选,如有冒犯,我先向您道歉,另还请告知我进行处理,谢谢
邮箱:thread_zhou@126.com