21个 JVM 技术点详解(附面试解答)

最近兄弟们面试,都逃不过被 JVM 问题轰炸的命运,为啥面试官喜欢拿 JVM 说事呢?V 哥认为,除了要问倒你,就是要压你薪水,咱绝对不能怂,俗话说的好:兵来将挡,水来土掩,流氓来了有啤酒......瓶。勇气来自深厚的技术功底,谁怕谁,来呗,开整!

当谈到 Java 编程语言时,Java 虚拟机(JVM)是其核心组成部分之一。JVM 是一个虚拟的计算机,它负责将 Java 字节码(.class 文件)翻译成特定平台上的机器码,并执行这些机器码以运行 Java 程序。以下V哥在教学中整理的 JVM 21个技术点,绝对完全覆盖JVM 的所有面试问题,文章太详细内容太多,建议收藏起来,夜深人静的时候安静的学习

1、类加载器(Class Loader):

类加载器负责将 Java 字节码加载到 JVM 中。JVM 包含了三个内置的类加载器:Bootstrap 类加载器、Extension 类加载器和 Application 类加载器。Bootstrap 类加载器负责加载 Java 核心类库,Extension 类加载器负责加载 Java 扩展库,而 Application 类加载器则负责加载应用程序的类。

1.1 类加载器的工作原理:

加载(Loading):类加载器首先通过类的全限定名(Fully Qualified Name)来定位并读取对应的字节码文件。这个过程可以是从文件系统、网络、JAR 文件等来源加载。

链接(Linking):
链接阶段包括三个步骤:验证(Verification)、准备(Preparation)和解析(Resolution)。

验证:确保字节码文件符合 Java 虚拟机规范,不会危害系统安全。

准备:为类的静态变量分配内存,并初始化为默认值。

解析:将类、接口、字段和方法的引用转换为直接引用。

初始化(Initialization):初始化阶段会执行类构造器(<clinit> 方法)的代码,对类的静态变量进行初始化赋值,执行静态代码块。

双亲委派模型(Delegation Model):类加载器采用双亲委派模型,即当一个类加载器接收到加载类的请求时,它首先会委托给父类加载器去完成加载,只有在父类加载器无法完成加载时,才会尝试自己加载。这个机制保证了类的统一性,避免了类的重复加载。

1.2 如何回答面试问题:

面试官问题: “请解释类加载器的工作原理,并举例说明其在实际应用中的作用。”

回答示例:

基本概念:
类加载器(Class Loader)是 Java 虚拟机(JVM)的一个重要组成部分,负责将 Java 类文件加载到内存中并进行初始化。它实现了 Java 的动态加载机制,允许程序在运行时动态加载和创建类。

工作流程:
当 Java 程序需要使用一个类时,类加载器首先会根据类的全限定名(Fully Qualified Name)来定位并读取对应的字节码文件。接着,在加载阶段,类加载器会将字节码文件加载到内存中,并创建对应的 Class 对象。紧接着是链接阶段,包括验证、准备和解析步骤,用于确保字节码文件的合法性,并进行一些预处理工作,如为静态变量分配内存等。最后,初始化阶段会执行类构造器的代码,对类的静态变量进行初始化赋值,并执行静态代码块。

双亲委派模型:
Java 类加载器采用了双亲委派模型,即当一个类加载器接收到加载类的请求时,它会先将这个请求委托给父类加载器去完成加载。只有当父类加载器无法完成加载时,当前类加载器才会尝试自己加载。这样做可以保证类的唯一性和一致性,避免类的重复加载和冲突。

应用和实例:
一个常见的实际应用是动态加载机制。例如,Web 服务器中的 Servlet 容器就会使用类加载器动态加载和卸载 Web 应用程序,从而实现热部署和动态扩展功能。另一个例子是模块化系统,如 OSGi(Open Service Gateway Initiative),它允许运行时动态安装、卸载和更新模块,通过自定义类加载器实现模块的隔离和动态加载。

安全性和性能:
类加载器对 Java 程序的安全性和性能有重要影响。例如,类加载器可以实现沙箱机制,限制某些代码只能访问特定的资源,提高程序的安全性。同时,合理优化类加载器的性能也可以提升程序的运行效率,减少不必要的资源消耗和加载时间。

挑战和深入思考:
类加载器面临的挑战包括类的热替换、版本冲突、类加载顺序等问题,了解这些挑战可以帮助开发人员更好地优化和调试程序。
此外,随着技术的发展,如何更好地利用类加载器实现模块化、动态化和安全化仍然是一个值得深入探讨的问题。

V哥说:通过这样详细的回答,你可以向面试官展示出对于类加载器的深刻理解,并通过具体的例子说明其在实际应用中的作用和意义。

2、字节码验证器(Bytecode Verifier):

字节码验证器确保加载到 JVM 中的字节码是合法且安全的。它会检查字节码是否符合 Java 虚拟机规范,并防止恶意代码对系统造成危害。

2.1 字节码验证器的工作原理:

目的:
字节码验证器的主要目的是确保加载到 JVM 中的字节码是符合 Java 虚拟机规范的,不会危害系统安全。

验证内容:
字节码验证器会对字节码文件进行一系列的验证操作,包括:

  • 格式验证(Format Verification):检查字节码文件的结构是否符合规范,如字节码的魔数、版本号、常量池等。

  • 语义验证(Semantic Verification): 检查字节码文件是否符合 Java 语言规范,如类型转换的合法性、方法调用的正确性等。

  • 字节码验证(Bytecode Verification):检查字节码文件的执行流程是否合法,避免潜在的安全漏洞和异常情况。

工作过程:
字节码验证器在加载字节码文件到 JVM 中时会执行以下工作过程:

首先,验证器会逐个读取字节码文件中的字节码指令,并按照指令的执行顺序进行分析。

然后,验证器会根据指令的类型和参数进行相应的验证操作,如检查类型转换是否合法、方法调用是否正确等。

最后,验证器会根据验证结果决定是否允许加载该字节码文件,如果验证通过,则将其加载到 JVM 中,否则抛出验证异常并拒绝加载。

安全性保障:
字节码验证器的工作可以有效地保障 Java 程序的安全性,防止恶意代码对系统造成危害。通过验证字节码的合法性和安全性,可以避免类似于缓冲区溢出、类型转换错误等安全漏洞。

2.2 如何回答面试问题:

面试官问题: “请详细解释字节码验证器的工作原理,并说明其在 Java 虚拟机中的作用。”

回答示例:

基本概念:
字节码验证器是 Java 虚拟机的一个重要组件,负责确保加载到 JVM 中的字节码文件是符合 Java 虚拟机规范的,不会危害系统安全。

工作原理:
描述字节码验证器的工作原理,包括格式验证、语义验证和字节码验证三个主要的验证步骤。
解释字节码验证器如何逐个读取字节码指令,并根据指令的类型和参数进行验证操作,最终决定是否允许加载该字节码文件。

安全性保障:
强调字节码验证器对于 Java 程序的安全性的重要性,通过验证字节码的合法性和安全性,可以有效地防止恶意代码对系统造成危害。
举例说明字节码验证器可以防止类似缓冲区溢出、类型转换错误等安全漏洞的发生,保护系统的稳定性和安全性。

实际应用:
提及字节码验证器在实际应用中的作用,如保护 Java 虚拟机免受恶意代码攻击、确保 Java 应用程序的稳定性和安全性等。
举例说明字节码验证器在 Java 虚拟机中的重要性,以及它如何保障 Java 程序的正常运行和安全性。

V哥说:通过这样详细的回答,你可以向面试官展示出对于字节码验证器的深刻理解,并通过具体的例子说明其在 Java 虚拟机中的作用和意义。

3、解释器(Interpreter)和即时编译器(Just-In-Time Compiler,JIT):

JVM 包含两种执行字节码的方式。一种是通过解释器,它逐行解释字节码并将其转换为本地机器码执行。另一种方式是即时编译器,它将字节码直接编译成本地机器码,以提高程序的执行速度。JVM 会根据代码的执行情况来决定是否将某些代码编译成本地机器码。

3.1 解释器的工作原理:

基本概念:
解释器是 JVM 中的一个组件,负责逐行解释执行 Java 字节码,将其转换为对应的机器码并执行。每次执行都需要解释器逐条解释字节码指令,然后通过 JVM 内部的执行引擎执行相应的机器码。

工作过程:
解释器会逐行读取字节码文件中的指令,并根据指令的类型和参数进行相应的操作。
每次执行都需要解释器重新解释字节码,这会导致较低的执行效率,特别是对于频繁执行的代码路径。

优点与缺点:
优点是解释器可以立即执行代码,无需等待编译的时间,适用于短期的交互式操作和快速的原型开发。
缺点是解释器执行效率较低,因为它需要在运行时逐行解释字节码,并且无法进行任何形式的代码优化。

3.2 即时编译器的工作原理:

基本概念:
即时编译器是 JVM 中的一个组件,负责将频繁执行的字节码方法动态编译成本地机器码,以提高程序的执行效率。

工作过程:
即时编译器会监视程序的执行情况,收集热点代码(Hot Spot),即经常执行的代码路径。
当发现一个热点代码时,即时编译器会将其编译成本地机器码,并将其存储在代码缓存中。
下次执行相同的代码路径时,JVM 将直接执行编译后的本地机器码,而不需要重新解释字节码,从而提高了程序的执行效率。

优点与缺点:
优点是即时编译器可以实现代码的即时优化,将热点代码编译成高效的本地机器码,从而提高程序的执行速度。
缺点是即时编译器需要花费额外的时间和资源来进行编译,可能会导致程序的启动时间较长,适用于长期运行的服务器应用程序。

3.3 如何回答面试问题:

面试官问题: “请详细解释解释器和即时编译器的工作原理,并说明它们之间的区别和优劣势。”

回答示例:

解释器的工作原理:
解释器是 JVM 中负责执行字节码的一种方式,它逐行解释字节码并将其转换为机器码执行。
解释器的优点是可以立即执行代码,无需等待编译,但缺点是执行效率较低,适用于短期交互和快速原型开发。

即时编译器的工作原理:
即时编译器会监视程序的执行情况,收集热点代码,并将其编译成本地机器码。
即时编译器的优点是可以实现代码的即时优化,提高程序的执行速度,但缺点是可能会增加启动时间和资源消耗。

区别和优劣势:
解释器适用于短期交互和快速原型开发,而即时编译器适用于长期运行的服务器应用程序。
解释器的优势是立即执行代码,而即时编译器的优势是提高了程序的执行效率。
解释器的缺点是执行效率较低,而即时编译器的缺点是可能会增加启动时间和资源消耗。

V哥说:通过这样详细的回答,你可以向面试官展示出对于解释器和即时编译器的深刻理解,并且清晰地说明它们之间的区别和优劣势。

4、垃圾收集器(Garbage Collector):

Java 虚拟机还负责管理内存的分配和释放。垃圾收集器定期扫描内存中不再使用的对象,并将其回收以便后续的内存分配。这减轻了开发人员对内存管理的负担,并减少了内存泄漏的可能性。

4.1 垃圾收集器的工作原理:

垃圾检测:
垃圾收集器会定期扫描程序的堆内存,查找不再被引用的对象。通过一种称为 “垃圾检测” 的算法,它确定哪些对象是不再被程序使用的。

标记-清除算法:
最基本的垃圾收集算法是标记-清除算法。它分为两个阶段:

  • 标记阶段:遍历堆中的对象,并标记出所有活动对象。
  • 清除阶段:清除所有未标记的对象,将其内存空间回收。

垃圾收集器类型:
JVM 提供了多种不同类型的垃圾收集器,如串行收集器、并行收集器、并发收集器等。每种垃圾收集器都有不同的优势和适用场景。

内存分代:
JVM 将堆内存划分为不同的代(Generation),如新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation)等。不同代使用不同的垃圾收集器,并采用不同的收集策略。当然还有1.8之后使用元数据区取代了永久代。

收集策略:
垃圾收集器还采用了不同的收集策略,如复制收集、标记-整理收集、增量收集等。这些策略旨在提高垃圾收集的效率和性能。

4.2 如何回答面试问题:

面试官问题: “

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

马剑威(威哥爱编程)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值