2.JVM面试高频题

2.1 java平台无关性如何体现(compile once;run anywhere)

Java源码首先被编译成字节码,再由不同平台的JVM进行解析,JAVA语言在不同平台上运行时候不需要重新编译,java虚拟机在执行字节码的时候,把字节码转换成具体平台上的机器指令。

为什么JVM不直接将源码解析成机器码进行执行

每次执行前都需要检查,整体性能都将受到影响;也可以将别的语言解析成字节码,增加平台语言的兼容性。

2.2 JVM的架构

JVM是一个内存中的虚拟机,这意味着JVM的存储就是内存。JVM大致分为四个部分:

①Class Loader:加载编译好的Class文件到内存;

②Execution Engine:负责对命令进行解析执行

③Native Interface(本地接口):融合不同开发语言的原生库为java所用

④Runtime Date Area:JVM内存空间结构模型

2.3 什么是反射

在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

反射就是把JAVA类中的一个个成分映射成JAVA对象

2.4谈谈ClassLoader

ClassLoader负责将Class文件里面的二进制数据流装载进系统,然后交给JAVA虚拟机进行连接、初始化操作。

Java默认提供的三个ClassLoader:

①BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库;

②Extension ClassLoader:称为扩展类加载器,负责加载Java的扩展类库;

③App ClassLoader:称为系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。

最后还有一种自定义加载类

2.5 什么是ClassLoader的双亲委派机制

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。

2.6 类的装载过程

加载:通过ClassLoader加载class文件字节码,生成Class对象

链接:①校验:class的正确性与安全性②准备:为类变量分配存储空间并设置类变量初始值③解析:JVM将常量池内的符号引用转换为直接引用

初始化:执行类变量赋值和静态代码块

loadClass和forName的区别?

loadClass 和forName都是显性加载方法(隐性加载方法为 new);Class.forName方法得到的Class是已经初始化完成的;Classloder.loadClass得到的class是还没有链接的,只是完成了第一步。

2.7 JAVA的内存模型

 

递归为什么会引发java.lang.StackOverflowError异常

因为递归函数会反复调用自身,由于虚拟栈的深度是有限的,栈帧数超出虚拟栈深度,从而引发异常。

2.8 JVM三大性能调优参数 -Xms -Xmx -Xss的含义

-Xms:堆的初始值

-Xmx:堆能达到的最大值

-Xss:规定了每个线程虚拟机栈的大小

2.9 JAVA内存模型中堆和栈的区别

静态存储:编译时确定每个数据目标在运行时的存储空间需求。

栈式存储:数据区需求在编译时未知,运行时模块入口前确定。

堆式存储:编译时或运行时模块入口都无法确定,动态分配。

二者的联系:引用对象、数组时,栈里定义变量保存堆中目标的首地址

答:栈比堆小,栈的效率比堆高,栈产生的碎片远小于堆,栈支持静态与动态分配,堆仅支持动态分配,栈能够由编译器自动释放,堆需要GC。

 

<think>好的,用户现在问的是JVM相关的高频面试。之前他们已经询问过n8n和Dify的面试,现在转向JVM,说明可能在准备Java方向的面试,特别是后端开发或者系统架构相关职位。需要确保回答覆盖JVM的核心知识点,并且提供清晰、有深度的解析。 首先,我需要回忆常见的JVM面试,比如内存结构、垃圾回收机制、类加载过程、性能调优等。用户可能希望得到详细的解答,而仅仅是问列表。所以每个问需要给出关键点和示例代码或配置。 然后,要注意用户之前的问结构,他们喜欢示例代码和对比表格,比如在之前的回答中使用了代码块和表格。因此,在回答JVM时,也应该采用类似的格式,比如用代码块展示JVM参数配置,用表格对比同GC算法的优缺点。 接下来,要确保问覆盖高频考点。例如,内存模型、GC算法、类加载机制、常见问排查、性能调优参数等。同时,每个问需要简明扼要的解释,避免冗长,但又要足够详细,让者能理解核心概念。 另外,用户可能希望了解如何将理论应用到实际工作中,比如如何分析内存泄漏、如何配置JVM参数来优化应用性能。因此,在回答中加入实际案例或配置示例会更有帮助。 最后,需要检查回答是否符合用户指定的格式,包括在末尾提出3-5个相关问,并确保相关问与内容紧密相关,能够引导用户进一步深入学习。</think>以下是 JVM 高频面试及详细解析,涵盖内存模型、GC 机制、性能调优等核心知识点: --- ### 1. **JVM 内存模型(运行时数据区)** ```java // 示例:JVM 内存区域划分 public class JVMStructure { // 程序计数器(线程私有) private int counter; // Java 堆(所有线程共享) private Object obj = new Object(); // Java 栈(线程私有) public void method() { int localVar = 10; // 局部变量存在栈帧中 } // 方法区(所有线程共享,存储类元数据) static final String CONSTANT = "Hello"; } ``` **关键点**: - **线程私有区域**:程序计数器、虚拟机栈、本地方法栈 - **线程共享区域**:Java 堆、方法区(JDK8 后 Metaspace 替代永久代) --- ### 2. **垃圾回收机制(GC)** **GC 算法对比**: | 算法 | 优点 | 缺点 | 适用场景 | |-------------|--------------------------|--------------------------|----------------------| | 标记-清除 | 简单高效 | 产生内存碎片 | 短暂对象多的场景 | | 标记-整理 | 消除碎片 | 效率较低 | 老年代 | | 复制 | 无碎片,效率高 | 空间利用率低 | 年轻代(Survivor 区)| | 分代收集 | 综合前三种优点 | 实现复杂 | 现代 JVM 默认策略 | **常见 GC 器**: - **Serial**:单线程 GC(适用于单核 CPU) - **Parallel Scavenge**:多线程吞吐优先(`-XX:+UseParallelGC`) - **CMS**:低延迟(标记-清除,易碎片) - **G1**:分区回收(平衡吞吐与延迟,`-XX:+UseG1GC`) --- ### 3. **类加载机制** **双亲委派模型流程**: ```java // 类加载器层次结构 public class ClassLoaderDemo { public static void main(String[] args) { System.out.println(ClassLoader.getSystemClassLoader()); // 应用类加载器 System.out.println(ClassLoader.getSystemClassLoader().getParent()); // 扩展类加载器 System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent()); // 引导类加载器(null) } } ``` **关键点**: - **加载顺序**:Bootstrap → Ext → System → 自定义 - **作用**:保证类的唯一性和安全性(如 `java.lang.Object` 被篡改) --- ### 4. **JVM 性能调优参数** ```bash # 常见 JVM 参数配置 java -Xms512m -Xmx512m \ # 初始/最大堆内存 -Xmn256m \ # 年轻代大小 -XX:SurvivorRatio=8 \ # Eden/Survivor 比例 -XX:+UseG1GC \ # 使用 G1 GC -XX:MaxGCPauseMillis=200 \ # 目标停顿时间 -XX:G1HeapRegionSize=4M \ # 区域大小 -XX:+PrintGCDetails \ # 输出 GC 详情 -jar myapp.jar ``` --- ### 5. **内存泄漏排查步骤** **实战流程**: 1. **监控指标**:通过 `jstat -gc <pid>` 观察老年代使用率 2. **生成堆快照**:`jmap -dump:format=b,file=heap.bin <pid>` 3. **分析工具**:使用 MAT(Memory Analyzer Tool)查看支配树 4. **典型场景**: - **静态集合类未清理**(如 `static Map`) - **监听器未注销**(如 `ServletContextListener`) - **线程池未关闭** --- ### 6. **JVM 内存溢出类型及解决** | 异常类型 | 原因及解决方案 | |------------------------|------------------------------------------| | `OutOfMemoryError: Java heap space` | 调整堆大小(`-Xmx`),检查内存泄漏 | | `OutOfMemoryError: Metaspace` | 增加元空间(`-XX:MaxMetaspaceSize`) | | `StackOverflowError` | 递归过深或线程栈大小足(`-Xss`) | | `OutOfMemoryError: Direct buffer memory` | 减少 `ByteBuffer.allocateDirect()` 使用 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值