Appearance
Java JVM面试题
1. JVM的基本概念
问题:什么是JVM?JVM的作用是什么?
答案:
- JVM(Java Virtual Machine):Java虚拟机,是Java程序运行的环境。
- 作用:
- 将Java字节码转换为特定平台的机器码并执行。
- 提供内存管理、垃圾回收、线程管理等功能。
- 实现平台无关性,一次编写,到处运行。
2. JVM的内存结构
问题:JVM的内存结构是怎样的?
答案:
JVM内存结构
├── 堆(Heap)
│ ├── 新生代(Young Generation)
│ │ ├── Eden区
│ │ └── Survivor区(From Survivor、To Survivor)
│ └── 老年代(Old Generation)
├── 方法区(Method Area)
│ ├── 类信息
│ ├── 常量池
│ └── 静态变量
├── 栈(Stack)
│ ├── 局部变量表
│ ├── 操作数栈
│ ├── 动态链接
│ └── 方法出口
├── 程序计数器(Program Counter Register)
├── 本地方法栈(Native Method Stack)
└── 直接内存(Direct Memory)3. 堆内存
问题:堆内存是如何划分的?
答案:
- 新生代:存放新创建的对象。
- Eden区:新创建的对象存放在Eden区。
- Survivor区:经过一次或多次GC后仍然存活的对象存放在Survivor区。
- 老年代:存放生命周期较长的对象。
4. 垃圾回收算法
问题:JVM中有哪些垃圾回收算法?
答案:
- 标记-清除算法:标记需要回收的对象,然后清除。缺点是产生内存碎片。
- 复制算法:将存活的对象复制到另一块内存,然后清除原内存。缺点是浪费一半内存。
- 标记-整理算法:标记需要回收的对象,然后将存活的对象整理到一端,然后清除另一端。
- 分代收集算法:根据对象存活周期的不同,将内存划分为不同的代,采用不同的收集算法。
5. 垃圾收集器
问题:JVM中有哪些垃圾收集器?
答案:
- Serial收集器:单线程收集器,适合单核CPU。
- Parallel收集器:多线程收集器,适合多核CPU。
- CMS收集器:并发标记清除收集器,以最短回收停顿时间为目标。
- G1收集器:面向服务端的收集器,将堆划分为多个Region,可预测停顿时间。
- ZGC收集器:低延迟垃圾收集器,停顿时间不超过10ms。
- Shenandoah收集器:低延迟垃圾收集器,停顿时间不超过10ms。
6. 类加载机制
问题:JVM的类加载机制是怎样的?
答案:
- 加载:查找并加载类的二进制数据。
- 验证:验证字节码的正确性。
- 准备:为类的静态变量分配内存并设置默认值。
- 解析:将符号引用转换为直接引用。
- 初始化:执行类的初始化代码,包括静态变量赋值和静态代码块。
7. 类加载器
问题:JVM中有哪些类加载器?
答案:
- 启动类加载器(Bootstrap ClassLoader):加载Java核心类,如java.lang.String。
- 扩展类加载器(Extension ClassLoader):加载Java扩展类,如javax.*包中的类。
- 应用程序类加载器(Application ClassLoader):加载应用程序的类。
- 自定义类加载器:用户自定义的类加载器。
8. 双亲委派模型
问题:什么是双亲委派模型?
答案:
- 双亲委派模型:类加载器在加载类时,先委托父类加载器加载,如果父类加载器无法加载,才由自己加载。
- 作用:
- 保证Java核心类的安全性。
- 避免类的重复加载。
9. JVM参数
问题:常用的JVM参数有哪些?
答案:
- 内存参数:
-Xms:初始堆大小。-Xmx:最大堆大小。-Xmn:新生代大小。-XX:MetaspaceSize:元空间初始大小。-XX:MaxMetaspaceSize:元空间最大大小。
- 垃圾回收参数:
-XX:+UseSerialGC:使用Serial收集器。-XX:+UseParallelGC:使用Parallel收集器。-XX:+UseConcMarkSweepGC:使用CMS收集器。-XX:+UseG1GC:使用G1收集器。
- 日志参数:
-XX:+PrintGCDetails:打印GC详细信息。-XX:+PrintGCTimeStamps:打印GC时间戳。-Xloggc:gc.log:将GC日志输出到文件。
10. JVM调优
问题:如何进行JVM调优?
答案:
- 内存调优:
- 设置合适的堆大小,避免频繁GC。
- 设置合适的新生代和老年代比例。
- 设置合适的元空间大小。
- 垃圾回收调优:
- 选择合适的垃圾收集器。
- 调整垃圾收集器的参数。
- 线程调优:
- 设置合适的线程栈大小。
- 避免创建过多的线程。
- 监控和分析:
- 使用jstat、jmap、jstack等工具监控JVM。
- 使用VisualVM、JProfiler等工具分析JVM性能。
11. 内存泄漏
问题:什么是内存泄漏?如何检测和解决?
答案:
- 内存泄漏:程序中不再使用的对象无法被垃圾回收,导致内存占用不断增加。
- 检测方法:
- 使用jmap查看堆内存使用情况。
- 使用jhat分析堆转储文件。
- 使用VisualVM、JProfiler等工具分析内存。
- 解决方法:
- 及时释放不再使用的对象引用。
- 使用弱引用、软引用等。
- 避免使用静态集合。
12. 内存溢出
问题:什么是内存溢出?如何解决?
答案:
- 内存溢出:程序需要的内存超过了JVM分配的内存。
- 解决方法:
- 增加JVM的内存大小。
- 优化程序,减少内存占用。
- 检查是否有内存泄漏。
13. 栈溢出
问题:什么是栈溢出?如何解决?
答案:
- 栈溢出:方法调用层次过深,导致栈空间不足。
- 解决方法:
- 增加线程栈大小。
- 优化程序,减少方法调用层次。
- 避免递归调用。
14. 垃圾回收
问题:垃圾回收的触发条件是什么?
答案:
- Minor GC:当Eden区满了时触发。
- Full GC:当老年代满了时触发,或者调用System.gc()时触发。
15. 对象的创建过程
问题:对象的创建过程是怎样的?
答案:
- 类加载:加载、验证、准备、解析、初始化。
- 分配内存:在堆中为对象分配内存。
- 初始化零值:将对象的内存设置为零值。
- 设置对象头:设置对象的类信息、哈希码、GC年龄等。
- 执行初始化方法:调用构造方法,初始化对象的字段。
16. 对象的内存布局
问题:对象的内存布局是怎样的?
答案:
- 对象头:
- Mark Word:存储对象的哈希码、GC年龄、锁状态等信息。
- 类型指针:指向对象的类信息。
- 实例数据:存储对象的字段值。
- 对齐填充:保证对象的内存大小是8字节的整数倍。
17. 对象的访问定位
问题:对象的访问定位方式有哪些?
答案:
- 句柄访问:通过句柄池访问对象,优点是对象移动时只需要修改句柄池中的指针。
- 直接指针访问:通过直接指针访问对象,优点是访问速度快。
18. 字符串常量池
问题:什么是字符串常量池?
答案:
- 字符串常量池:JVM中专门存储字符串常量的区域。
- 作用:
- 避免重复创建字符串对象。
- 节省内存空间。
示例:
java
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // true,指向同一个字符串常量
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println(s3 == s4); // false,不同的对象19. 运行时常量池
问题:什么是运行时常量池?
答案:
- 运行时常量池:JVM在运行时创建的常量池,包含类文件中的常量池和运行时生成的常量。
- 作用:
- 存储字面量和符号引用。
- 提高程序性能。
20. 方法区
问题:方法区的作用是什么?
答案:
- 方法区:存储类的信息、常量池、静态变量等。
- 作用:
- 存储类的结构信息,如字段、方法、构造方法等。
- 存储常量池,如字符串常量、类名、方法名等。
- 存储静态变量。
21. 元空间
问题:什么是元空间?
答案:
- 元空间:Java 8引入的,用于替代永久代。
- 区别:
- 元空间使用本地内存,而永久代使用堆内存。
- 元空间可以动态调整大小,而永久代大小固定。
- 元空间不会发生Full GC,而永久代会发生Full GC。
22. 直接内存
问题:什么是直接内存?
答案:
- 直接内存:JVM之外的内存,通过Unsafe类或NIO的ByteBuffer.allocateDirect()方法分配。
- 作用:
- 避免在Java堆和本地内存之间复制数据。
- 提高IO性能。
23. JIT编译
问题:什么是JIT编译?
答案:
- JIT(Just-In-Time)编译:将字节码编译成本地机器码,提高程序执行速度。
- 作用:
- 提高程序执行速度。
- 根据运行时信息进行优化。
24. C1编译器和C2编译器
问题:C1编译器和C2编译器有什么区别?
答案:
- C1编译器:客户端编译器,编译速度快,优化程度低。
- C2编译器:服务端编译器,编译速度慢,优化程度高。
25. 分层编译
问题:什么是分层编译?
答案:
- 分层编译:根据方法的执行频率,选择不同的编译器进行编译。
- 层次:
- 第0层:解释执行。
- 第1层:C1编译,无profiling。
- 第2层:C1编译,有限profiling。
- 第3层:C1编译,完全profiling。
- 第4层:C2编译。
