JVM:字节码

前言

请添加图片描述

1. JVM概述

1.1 JVM vs JDK vs JRE

1.1.1 JVM

Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。
JVM 并不是只有一种!只要满足 JVM 规范,每个公司、组织或者个人都可以开发自己的专属 JVM。 也就是说我们平时接触到的 HotSpot VM 仅仅是是 JVM 规范的一种实现而已。除了我们平时最常用的 HotSpot VM 外,还有 J9 VM、Zing VM、JRockit VM 等 JVM 。

1.1.2 JDK

JDK(Java 开发工具包):JDK 是 Java 程序的开发环境,它包含了用于开发、编译和调试 Java 程序所需的工具和库。JDK 包括了 JRE 和一系列开发工具,如编译器(javac)、调试器(jdb)、JavaDoc 工具等。JDK 还提供了 Java 标准库和其他开发所需的类库。

1.1.2.1 常用的JDK8是Oracle JDK 还是 OpenJDK

在 JDK 8 的时代,Oracle JDK 和 OpenJDK 都是常见的选择。一般来说,Oracle JDK 8 是比较常用的版本,因为它在 JDK 8 发布时是主要的 JDK 提供商 。Oracle JDK 8 在商业环境中提供了长期支持,同时还包含了一些额外的闭源组件。

然而,自 JDK 11 开始,Oracle 将其 JDK 的开发重点转向了 OpenJDK,并且 Oracle JDK 11 及以后的版本使用 GPL 许可协议,与 OpenJDK 保持一致。这意味着从 JDK 11 开始,OpenJDK 成为了更广泛使用的选择,因为它是免费的、开源的,并且由广大的开源社区支持。

总的来说,对于 JDK 8,Oracle JDK 是常见的选择,但对于更高版本的 JDK,OpenJDK 更为普遍。

1.1.3 JRE

JRE(Java 运行时环境):JRE 是 Java 程序的运行环境,它是 JVM 的一部分。JRE 包含了 JVM 和 Java 类库,用于执行已编译的 Java 程序。它提供了 Java 应用程序所需的运行时支持,包括线程管理、I/O、网络通信等功能。对于只需要运行 Java 程序的用户来说,安装 JRE 即可。

1.1.4 三者之间的关系与区别

  • JDK 包含了 JRE,JDK 是开发环境,提供了编译器和其他开发工具,而 JRE 是运行环境,用于执行已编译的 Java 程序。
  • JRE 包含了 JVM,JVM 是 Java 程序的运行环境,负责将字节码翻译成机器码并提供运行时支持。
  • JDK 不仅包含了 JRE 和 JVM,还提供了用于开发 Java 程序所需的工具和类库。
    在这里插入图片描述

1.2 什么是字节码?采用字节码的好处是什么?

在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以, Java 程序运行时相对来说还是高效的(不过,和 C、 C++,Rust,Go 等语言还是有一定差距的),而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。

1.3 Java 程序从源代码到运行的过程

在这里插入图片描述
我们需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT(Just in Time Compilation) 编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言 。

在这里插入图片描述
HotSpot 采用了惰性评估(Lazy Evaluation)的做法,根据二八定律,消耗大部分系统资源的只有那一小部分的代码(热点代码),而这也就是 JIT 所需要编译的部分。JVM 会根据代码每次被执行的情况收集信息并相应地做出一些优化,因此执行的次数越多,它的速度就越快。

1.4 JVM的生命周期

1.虚拟机的启动
Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。

2.虚拟机的退出有如下的几种情况:

  • 某线程调用Runtime类或System类的exit方法,或 Runtime类的halt方法,并且Java安全管理器也允许这次exit或halt操作。
  • 程序正常执行结束。
  • 程序在执行过程中遇到了异常或错误而异常终止。
  • 由于操作系统出现错误而导致Java虚拟机进程终止 。

1.5 JVM架构图

在这里插入图片描述

2. 字节码

2.1 字节码文件是跨平台的吗?

是的
在这里插入图片描述

2.2 class文件里面是什么?

3. 解释器与JIT编译器

解释器(Interpreter)和 JIT 编译器(Just-In-Time Compiler)都是用于执行程序的工具,但它们的工作方式和作用有所不同。

解释器(Interpreter):

  1. 解释器是一种逐行执行程序代码的工具。它会逐行读取源代码,并将其转换成计算机可以理解的机器语言,然后执行这些指令。
  2. 解释器不会将整个程序代码一次性地转换成机器语言,而是在运行时逐行地解释和执行源代码。
  3. 由于逐行解释的特性,解释器的执行速度通常比较慢,尤其是对于循环和复杂逻辑的程序。

JIT 编译器(Just-In-Time Compiler):

  1. JIT 编译器是一种在运行时将程序代码动态地编译成机器语言的工具。它可以将整个函数或代码块编译成机器代码,然后直接执行编译后的机器代码。
  2. JIT 编译器通常会在程序首次执行时或者某个函数首次被调用时进行编译,以后再次执行相同代码时就可以直接使用编译后的机器代码,从而提高了程序的执行速度。 但这里注意,其实Java是半编译半解释型语言,热点代码会先经过解释器解释称字节码文件,待下次执行时直接在JIT编译器执行
  3. JIT 编译器通常会根据程序的运行情况和环境动态地进行优化,以提高程序的执行效率。

在这里插入图片描述

AOT编译器

在这里插入图片描述

4. 字节码文件概述

4.1 字节码文件里是什么?

源代码经过编译器编译之后便会生成一个字节码文件,字节码是一种二进制的类文件,它的内容是JVM的指令,而不像C、C++经由编译器直接生成机器码。
在这里插入图片描述

4.2 生成class文件的编译器

生成class文件的编译器如下
在这里插入图片描述

  1. 从位置上理解前端编译器 vs 后端编译器 半编译半解释型语言!
  2. 前端编译器的种类Java源代码的编译结果是字节码,那么肯定需要有一种编译器能够将Java源码编译为字节码,承担这个重要责任的就是配置在path环境变量中的javac编译器。javac是一种能够将Java源码编译为字节码的前端编译器。
  3. HotSpot VM并没有强制要求前端编译器只能使用javac来编译字节码,其实只要编译结果符合JVM规范都可以被JVM所识别即可。在Java的前端编译器领域,除了javac之外,还有一种被大家经常用到的前端编译器,那就是内置在Eclipse中的ECJ (Eclipse Compiler for Java)编译器。和Javac的全量式编译不同,ECJ是一种增量式编译器。 在Eclipse中,当开发人员编写完代码后,使用“Ctrl+S”快捷键时,ECJ编译器所釆取的编译方案是把未编译部分的源码逐行进行编译,而非每次都全量编译。因此ECJ的编译效率会比javac更加迅速和高效,当然编译质量和javac相比大致还是一样的。ECJ不仅是Eclipse的默认内置前端编译器,在Tomcat中同样也是使用ECJ编译器来编译jsp文件。由于ECJ编译器是釆用GPLv2的开源协议进行源代码公开,所以,大家可以登录eclipse官网下载ECJ编译器的源码进行二次开发。默认情况下,IntelliJ IDEA 使用 javac 编译器。(还可以自己设置为AspectJ编译器 ajc)
  4. 前端编译器的任务前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件。

5. 字节码相关面试题

5.1 什么是字节码指令(byte code)?

Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的操作码(opcode)以及跟随其后的零至多个代表此操作所需参数的操作数(operand)所构成。虚拟机中许多指令并不包含操作数,只有一个操作码。比如:
在这里插入图片描述

5.2 i++ 与 ++i的区别

字节码文件一样的
在这里插入图片描述

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boy快快长大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值