【面试题】JVM面试题及答案总结

JVM(Java虚拟机)是Java技术体系的核心,面试中经常会被问到与JVM相关的问题,

以下是一些典型的JVM面试题及答案概要:

JVM的主要组成部分有哪些?

  • 类加载器(ClassLoader):负责从文件系统或网络等位置加载.class文件,并将这些字节码转换成方法区的运行时数据结构。
  • 运行时数据区(Runtime Data Area):
    • 程序计数器(Program Counter Register):线程私有,存储当前正在执行的指令地址。
    • 虚拟机栈(Java Virtual Machine Stacks):线程私有,每个方法在执行时会创建一个栈帧(Stack Frame),用于存放局部变量表、操作数栈、动态链接和方法出口信息等。
    • 本地方法栈(Native Method Stack):与虚拟机栈类似,为虚拟机使用到的Native方法服务。
    • 堆(Heap):所有线程共享,存放对象实例以及数组。
    • 方法区(Method Area):所有线程共享,存储已被加载的类的信息、常量池、静态变量、即时编译器编译后的代码等数据
  • 执行引擎(Execution Engine):负责执行字节码,包括解释执行和通过JIT(Just-In-Time)编译器进行的热点代码优化编译执行。
  • 本地库接口(Native Interface):允许Java代码调用底层操作系统或硬件的接口。

Java内存溢出错误主要有哪些类型?

  • Java heap space out of memory error:堆空间不足,通常由于对象过多或者单个对象过大导致。
  • PermGen space out of memory error (或Metaspace for Java 8以上版本):方法区空间不足,常见于大量类的动态加载或者反射生成大量类信息时。
  • StackOverflowError:虚拟机栈或本地方法栈深度过深,如递归调用层次太深且未及时返回导致栈空间耗尽。
  • DirectBuffer分配内存溢出:直接内存(Direct Memory)超过其上限。

什么是垃圾收集(GC)?GC算法有哪些?

垃圾收集是JVM用来自动回收不再使用的对象所占用的内存的过程。常见的垃圾收集算法包括:

  • 标记-清除(Mark-Sweep):先标记出所有活动对象,然后清除未被标记的对象。
  • 复制(Copying):将内存划分为两块,只有一块用于分配对象,当这块内存满了之后,就将存活的对象复制到另一块上,然后清空已使用的那块区域。
  • 标记-压缩(Mark-Compact):结合了标记-清除和复制的思想,标记阶段找出所有活动对象后,压缩它们到内存的一端,消除碎片。
  • 分代收集(Generational Collection):基于年轻代(Eden, Survivor Space)和老年代(Tenured Generation)的不同特性,采用不同的收集策略,如新生代的Copying算法(如Parallel Scavenge)、老年代的Mark-Sweep-Compact算法(如Serial Old、Parallel Old)等。

什么是类加载机制,类加载过程包含哪几个步骤?

类加载机制是JVM实现把.class文件中的二进制数据转换为方法区中运行时数据结构的过程。类加载过程包括以下几个阶段:

  • 加载(Load):通过类的全限定名找到对应的.class文件并读入内存,创建一个代表该类的Class对象。
  • 验证(Verification):确保被加载类的正确性,例如检查类文件格式、元数据、字节码验证等。
  • 准备(Preparation):给类的静态变量分配内存,并初始化为默认值。
  • 解析(Resolution):将符号引用转换为直接引用,如将字符串常量池中的字符串引用解析为实际的内存地址。
  • 初始化(Initialization):执行类构造器方法,对静态变量进行初始化赋值。

JVM中的双亲委派模型是什么?

双亲委派模型是Java类加载器的一种工作模式。当一个类加载器收到类加载请求时,首先不会自己尝试加载,而是将这个请求委派给父加载器去完成。每一层次的类加载器都是如此,因此所有的加载请求最终都会传送到顶层的启动类加载器。只有当父加载器无法完成类加载(即找不到指定类)时,子加载器才会尝试自己去加载。

这样做的好处在于保证了Java应用的各个类库版本的一致性,避免了由于类重复加载而导致的安全性和稳定性问题。

Java对象什么时候可以被垃圾回收?

Java对象在以下条件满足时可以被垃圾回收:

  • 对象不再有任何引用指向它,无论是强引用、软引用、弱引用还是虚引用。
  • 对象是可达的,但其关联的引用类型已经进入相应的引用队列。
    具体来说,当一个对象没有任何途径再被程序访问到,也就是不可达时,将会被视为可回收的对象。垃圾收集器会在合适的时机进行回收操作。

请解释一下Minor GC和Full GC的区别?

Minor GC:发生在年轻代(Young Generation)的垃圾回收。年轻代包括Eden区和两个Survivor区,当年轻代空间不足时会触发Minor GC。 Minor GC相对频繁且速度较快,因为年轻代的对象生命周期通常较短,大部分对象会被回收。

Full GC:发生在整个堆内存中,包括年轻代和老年代(Tenured Generation)以及方法区(对于HotSpot虚拟机还包括元空间Metaspace)。Full GC一般发生在老年代空间不足,或者System.gc()显式调用,或者CMS并发清理失败等情况。Full GC比Minor GC更耗费时间,因为它涉及的对象范围更广,影响更大。


介绍一下JVM调优工具JConsole和VisualVM的作用?

JConsole:Java自带的一个GUI监控工具,用于对本地或远程Java应用程序进行性能监控和故障排查。它可以显示线程、内存、类加载、CPU使用率等信息,并支持动态查看MBean属性和执行MBean操作。

VisualVM:是一个功能更加强大的JDK工具套件,提供了更全面的应用程序分析功能,包括内存分析、线程分析、CPU分析、类加载分析等。VisualVM还支持插件扩展,可以安装如Memory Sampler、Thread Dump Analyzer等高级功能模块,帮助开发者深入了解JVM运行状态,进行性能瓶颈定位和JVM参数调优。


说说你了解的几种常用的JVM参数及其作用?

-Xms 和 -Xmx:分别设置Java进程初始堆大小和最大堆大小,例如 -Xms2g -Xmx4g 表示初始堆为2GB,最大堆为4GB。
-XX:NewRatio:设置年轻代与老年代的比例,默认值根据平台不同而不同,例如 -XX:NewRatio=3 表示年轻代与老年代的内存比例为1:3。
-XX:MaxTenuringThreshold:设置对象晋升到老年代的年龄阈值,默认值是15。年轻代中经历多次Minor GC后依然存活的对象将会晋升至老年代。
-XX:+UseConcMarkSweepGC 或 -XX:+UseG1GC 等:选择不同的垃圾收集器,比如CMS垃圾收集器或G1垃圾收集器。
-XX:PermSize 和 -XX:MaxPermSize(Java 8之前有效):设置永久代的初始大小和最大大小,但在Java 8及以后版本,永久代已被元空间(Metaspace)取代,相应参数为 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize。


什么是Java内存模型(JMM)?

Java内存模型(Java Memory Model, JMM)是一种规范,它定义了Java虚拟机如何与计算机硬件内存进行交互以及在多线程环境下如何同步和通信。JMM确保了并发编程中的原子性、可见性和有序性。它解决了由于处理器重排序、缓存一致性等问题可能带来的并发编程中的数据不一致问题。


解释一下JVM中的HotSpot及其优化策略?

HotSpot是Oracle JDK中使用的一种高性能的JVM实现,它采用了多种优化技术,包括:

**即时编译器(JIT):**HotSpot JVM包含多个即时编译器(C1、C2),将热点代码从字节码转换为机器码,通过方法内联、循环展开等优化提高执行效率。

**动态编译优化:**根据运行时数据对热点代码进行持续优化,例如分支预测、逃逸分析、栈上替换(On-Stack Replacement, OSR)等。

**垃圾收集优化:**提供不同的垃圾回收器如Serial GC、Parallel GC、CMS GC、G1 GC、ZGC和Shenandoah GC,并支持各种调优参数以适应不同应用的需求。


什么是类卸载机制?类何时会被卸载?

类卸载是指JVM从方法区中移除不再使用的类的信息,释放其占用的内存空间。类被卸载需要满足以下条件:

  • 类的所有实例都已被回收。
  • 加载该类的类加载器已经被回收。
  • 该类的Class对象没有在任何地方被引用,即不可达。

类卸载由系统自动进行,无需开发者显式操作,但需要注意的是,如果应用程序设计不当,可能会导致类永不卸载,从而引发长期运行的应用程序内存泄漏问题。


如何避免死锁的发生,尤其是在JVM中?

在JVM环境中避免死锁通常需要遵循以下原则:

  • 避免一个线程同时占有两个以上的资源而不释放已占有的资源。
  • 使用资源请求时设置超时时间,超时后主动释放持有的资源并重新尝试。
  • 按照既定的全局顺序申请资源,避免循环等待。
  • 尽量减少同步区域,只在必要的时候持有锁。
  • 使用高级并发工具,如java.util.concurrent包提供的锁、信号量和队列等,它们提供了更细粒度的控制和更高的容错性。

Java中有哪些常见的内存泄漏类型,并给出相应的解决方案?

常见的Java内存泄漏类型包括:

  • 静态集合类引起的内存泄漏:静态集合类会一直存活到应用程序结束,若其中存储的对象不再使用,也会无法被回收。解决方案是定期清理无用对象或在不再使用时手动从集合中移除。
  • 长生命周期对象持有短生命周期对象引用:当长生命周期的对象持有短生命周期对象的引用,而短生命周期对象不再使用时,由于强引用的存在,垃圾回收器无法回收这些对象。解决办法是适时断开不必要的引用,比如使用弱引用或软引用。
  • 监听器/回调函数未注销:注册到某个服务或者框架中的监听器或回调函数,如果没有正确地反注册,可能会导致对象不能被回收。应确保在组件不再使用时及时取消注册。

  • 24
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 什么是JVMJVM(Java Virtual Machine)是Java虚拟机的缩写,是Java程序运行的环境。 2. JVM的组成部分有哪些? JVM加载器、运行时数据区、执行引擎和本地库接口组成。 3. 加载器有哪些? 加载器有三种:启动加载器、扩展加载器和应用程序加载器。 4. 什么是加载器? 加载器是Java虚拟机的一个组成部分,它负责将文件加载到JVM中。 5. 什么是加载器的双亲委派模型? 加载器的双亲委派模型是一种加载器的层级结构,当一个需要被加载时,它的父加载器会先尝试加载这个,如果父加载器不能加载这个,它才会把这个请求传给子加载器。 6. 什么是内存泄漏? 内存泄漏是指应用程序在运行时未能及时释放无用的内存,导致内存空间的浪费和程序性能的下降。 7. JVM中的运行时数据区有哪些? JVM中的运行时数据区有程序计数器、虚拟机栈、本地方法栈、堆和方法区。 8. 什么是程序计数器? 程序计数器是一块较小的内存空间,它用于保存当前线程执行的字节码指令地址。 9. 什么是虚拟机栈? 虚拟机栈是一块内存空间,用于保存方法执行时的局部变量表、操作数栈、动态链接、方法出口等信息。 10. 什么是本地方法栈? 本地方法栈是一块内存空间,用于支持JVM调用本地方法的功能。 11. 什么是堆? 堆是JVM中最大的一块内存空间,用于存放对象实例和数组等数据。 12. 什么是方法区? 方法区是一块内存空间,用于存放的元数据信息、常量池、静态变量、方法信息等。 13. JVM中的垃圾回收算法有哪些? JVM中的垃圾回收算法有标记-清除算法、复制算法、标记-整理算法和分代算法等。 14. 什么是标记-清除算法? 标记-清除算法是一种垃圾回收算法,它分为标记和清除两个阶段,先标记出所有需要回收的对象,然后再回收这些对象所占用的内存空间。 15. 什么是复制算法? 复制算法是一种垃圾回收算法,它将堆空间分为两个相等的区域,每次只使用其中一个区域,当这个区域用完时,将其中的存活对象复制到另一个区域中,然后清空原来的区域。 16. 什么是标记-整理算法? 标记-整理算法是一种垃圾回收算法,它先标记出所有需要回收的对象,然后将存活对象往一端移动,然后将空闲的内存空间清理掉。 17. 什么是分代算法? 分代算法是一种垃圾回收算法,它将堆空间分为新生代和老年代两个区域,新生代内存空间小,存活时间短,采用复制算法;老年代内存空间大,存活时间长,采用标记-清除算法或标记-整理算法。 18. 什么是强引用? 强引用是指在程序中直接定义的引用型变量,只要强引用存在,垃圾回收器就不会回收被引用的对象。 19. 什么是软引用? 软引用是一种相对弱化的引用型,如果JVM内存空间不足,垃圾回收器会回收被软引用引用的对象。 20. 什么是弱引用? 弱引用是一种更弱化的引用型,它的引用对象只要没有被强引用或软引用所引用,就会被垃圾回收器回收。 21. 什么是虚引用? 虚引用是一种最弱化的引用型,它本身并不能引用对象,它的作用是在对象被回收时收到一个通知。 22. 什么是的生命周期? 的生命周期包括加载、验证、准备、解析、初始化、使用和卸载等阶段。 23. 什么是的加载阶段? 的加载阶段是指将的字节码文件加载到JVM中,并生成一个对应的Class对象。 24. 什么是的验证阶段? 的验证阶段是指对的字节码文件进行验证,以确保它符合JVM规范。 25. 什么是的准备阶段? 的准备阶段是指为的静态变量分配内存,并赋予默认值。 26. 什么是的解析阶段? 的解析阶段是指将的符号引用转换为直接引用。 27. 什么是的初始化阶段? 的初始化阶段是指执行的静态初始化代码块。 28. 什么是的使用阶段? 的使用阶段是指使用的方法或变量。 29. 什么是卸载阶段? 卸载阶段是指将JVM卸载,释放内存空间。 30. 什么是JVM调优? JVM调优是指通过调整运行时数据区、垃圾回收算法、内存分配策略等方式,优化JVM的性能和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

泽济天下

你的鼓励是我最大的动力。

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

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

打赏作者

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

抵扣说明:

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

余额充值