JVM常见面试题及答案

1. 什么是JVM?它的作用是什么?

答案

JVM(Java Virtual Machine)是Java虚拟机的缩写,它是Java程序运行的执行环境。JVM的作用包括:

  • 加载.class文件
  • 验证字节码
  • 执行字节码
  • 提供运行时环境
  • 内存管理(垃圾回收)
  • 平台无关性("一次编写,到处运行")

2. JVM内存区域如何划分?

答案

JVM内存主要分为以下几个区域:

  1. 程序计数器:线程私有,记录当前线程执行的字节码行号
  2. 虚拟机栈:线程私有,存储局部变量表、操作数栈、动态链接、方法出口等
  3. 本地方法栈:为Native方法服务
  4. :线程共享,存放对象实例和数组,是GC主要区域
  5. 方法区:线程共享,存储类信息、常量、静态变量、即时编译器编译后的代码等

(JDK8后,方法区的实现从永久代改为元空间)

3. 什么是Java垃圾回收机制?常见的垃圾回收算法有哪些?

答案

垃圾回收是JVM自动管理内存的机制,用于回收不再使用的对象所占用的内存空间。

常见垃圾回收算法:

  • 标记-清除算法:标记所有需要回收的对象,然后统一回收
  • 复制算法:将内存分为两块,每次使用一块,存活对象复制到另一块
  • 标记-整理算法:标记后让所有存活对象向一端移动,然后清理边界外内存
  • 分代收集算法:根据对象存活周期将堆分为新生代和老年代,分别采用不同算法

4. 什么是类加载机制?类加载的过程是什么?

答案

类加载机制是JVM将.class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被JVM直接使用的Java类型的过程。

类加载过程分为5个阶段:

  1. 加载:查找并加载类的二进制数据
  2. 验证:确保被加载的类的正确性
  3. 准备:为类的静态变量分配内存并设置初始值
  4. 解析:将符号引用转换为直接引用
  5. 初始化:执行类构造器<clinit>()方法的过程

5. 什么是双亲委派模型?有什么好处?

答案

双亲委派模型是JVM类加载的一种工作机制,要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。

工作流程:

  1. 当前类加载器首先检查是否已加载过该类
  2. 如果没有,则委托父类加载器加载
  3. 父类加载器无法完成加载时,子类加载器才会尝试加载

好处:

  • 避免类的重复加载
  • 防止核心API被篡改(安全考虑)
  • 保证Java核心库的类型安全

6. JVM有哪些常见的性能调优参数?

答案

常见JVM调优参数:

  • 堆内存设置

    • -Xms:初始堆大小
    • -Xmx:最大堆大小
  • 新生代设置

    • -Xmn:新生代大小
    • -XX:SurvivorRatio:Eden和Survivor区比例
  • 垃圾回收器选择

    • -XX:+UseSerialGC:串行收集器
    • -XX:+UseParallelGC:并行收集器
    • -XX:+UseConcMarkSweepGC:CMS收集器
    • -XX:+UseG1GC:G1收集器
  • 其他

    • -XX:MaxPermSize:永久代大小(JDK7及之前)
    • -XX:MetaspaceSize:元空间初始大小(JDK8+)
    • -XX:MaxMetaspaceSize:元空间最大大小(JDK8+)

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

答案

Java内存模型(Java Memory Model)定义了Java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量的底层细节。

JMM主要特性:

  • 原子性:基本数据类型的访问读写是原子性的
  • 可见性:一个线程修改了共享变量的值,其他线程能够立即得知
  • 有序性:禁止指令重排序优化

JMM通过volatile、synchronized、final等关键字和happens-before原则来保证多线程环境下的正确性。

8. 什么是OOM?常见的OOM有哪些类型?

答案

OOM(OutOfMemoryError)是Java中的内存溢出错误,常见类型包括:

  1. Java堆空间溢出(OutOfMemoryError: Java heap space):对象数量达到堆容量限制
  2. 永久代/元空间溢出(OutOfMemoryError: PermGen space/Metaspace):类信息过多
  3. GC开销限制超出(OutOfMemoryError: GC overhead limit exceeded):GC时间过长
  4. 无法创建新线程(OutOfMemoryError: unable to create new native thread):线程数过多
  5. 直接内存溢出(OutOfMemoryError: Direct buffer memory):NIO直接内存不足

9. 解释强引用软引用弱引用虚引用的区别

答案

  1. 强引用:最常见的引用,只要强引用存在,垃圾回收器永远不会回收被引用的对象
  2. 软引用(SoftReference):内存不足时会被回收,适合做缓存
  3. 弱引用(WeakReference):无论内存是否足够,只要GC就会被回收
  4. 虚引用(PhantomReference):最弱的引用,无法通过它获取对象实例,主要用于跟踪对象被回收的活动

10. 什么是逃逸分析?有什么作用?

答案

逃逸分析是一种分析对象作用域的技术,用于分析对象的动态作用域,判断对象是否会被外部方法或线程访问。

作用:

  1. 栈上分配:如果对象不会逃逸出方法,可以在栈上分配内存,减少GC压力
  2. 同步消除:如果对象不会逃逸出线程,可以消除对该对象的同步操作
  3. 标量替换:将对象分解为若干个基本数据类型,直接在栈上分配

11. 常见的垃圾收集器有哪些?各自的特点是什么?

答案

  1. Serial收集器:单线程,新生代复制算法,老年代标记-整理算法
  2. ParNew收集器:Serial的多线程版本,与CMS配合使用
  3. Parallel Scavenge收集器:吞吐量优先,新生代复制算法,老年代标记-整理算法
  4. CMS收集器:低延迟,标记-清除算法,有内存碎片问题
  5. G1收集器:区域化分代式,整体标记-整理,局部复制算法,可预测停顿时间
  6. ZGC收集器:JDK11引入,低延迟,支持TB级堆内存
  7. Shenandoah收集器:低延迟,与ZGC竞争

12. 什么是JIT编译器?它是如何工作的?

答案

JIT(Just-In-Time)编译器是JVM的一部分,负责将热点代码(频繁执行的代码)编译为本地机器码,以提高执行效率。

工作过程:

  1. 解释器首先解释执行字节码
  2. 识别热点代码(方法调用计数器、回边计数器)
  3. JIT编译器将热点代码编译为本地机器码
  4. 后续执行直接使用编译后的机器码

JVM中有两种JIT编译器:C1(Client Compiler)和C2(Server Compiler),GraalVM还引入了新的JIT编译器。

完整版面试题库+:zhaowajiaoyu111

相关推荐
喵手1 分钟前
Java中Stream与集合框架的差异:如何通过Stream提升效率!
java·后端·java ee
JavaArchJourney2 分钟前
PriorityQueue 源码分析
java·源码
喵手12 分钟前
你知道,如何使用Java的多线程机制优化高并发应用吗?
java·后端·java ee
渣哥27 分钟前
10年Java老司机告诉你:为什么永远不要相信浮点数相等
java
Faith-小浩浩1 小时前
macos 多个版本的jdk
java·macos·jdk
喵手1 小时前
Java异常处理最佳实践:如何避免捕获到不必要的异常?
java·后端·java ee
猿java1 小时前
精通MySQL却不了解OLAP和 OLTP,正常吗?
java·后端·面试
渣哥1 小时前
面试官:为什么阿里巴巴要重写HashMap?ConcurrentHashMap哪里不够用?
java
喵手1 小时前
Java中的HashMap:你了解它的工作原理和最佳实践吗?
java·后端·java ee
weixin_456588152 小时前
【java面试day16】mysql-覆盖索引
java·mysql·面试