JVM相关

本文深入探讨Java中的垃圾回收机制,包括类加载器的种类、双亲委派模型、垃圾回收的基本概念及其算法,如标记-清除、标记-整理、标记-复制等。此外,还介绍了分代收集理论和具体的垃圾回收器,如CMS与G1垃圾回收器的特点及适用场景。

1.类加载器的种类

在这里插入图片描述

2.双亲委派模型

在这里插入图片描述

3.垃圾回收

在这里插入图片描述

在这里插入图片描述

4.什么是垃圾

在这里插入图片描述

可达性分析算法

  • 从GC Roots作为根对象开始,根据引用关系向下搜索,搜索走过的路程成为”引用链“,如果某个对象到GC Roots没有任何引用链相连,则这个对象是不可能再被使用(垃圾)

可作为GC Roots的对象

  • 在虚拟机栈引用的对象,比如局部变量,临时变量等
  • 方法区中的静态属性引用对象
  • 方法区中常量引用对象
  • 所有被同步锁Synchronized持有的对象

5.内存溢出OOM

当java虚拟机的堆内存不够,其原因可能有二:

- java虚拟机的堆内存设置不够
堆的大小不合理,比如要处理比较可观的数据量,但是没有显式的指定jvm堆大小或者指定数值偏小,我们可以通过参数-Xms、-Xmx来调整。
- 代码创建了大量对象,并且长时间不能被回收

6.内存泄漏

当对象不会再被使用到,但是GC又不能回收,这就是内存泄漏

在这里插入图片描述

  • 例子
    当一个变量是方法中的局部变量他的生命周期较短,但是如果定义为成员变量,甚至静态变量就是极大的拉长他的生命周期,大量的静态变量有可能导致内存泄漏
    在这里插入图片描述

7.垃圾回收器

评价GC的性能指标

- 吞吐量
运行用户代码的时间占总运行时间的比例
- 暂停时间
执行垃圾收集时,程序的工作线程被暂停的时间,暂停时间越短越好

这两个指标是垃圾回收器最为关注的,但是"高吞吐量”和“低暂停时间”是一对相互竞争的目标
在这里插入图片描述

7.垃圾回收算法

  • 一般用<可达性分析算法>判断对象是否存活。

  • 分代收集理论

    • 弱分代假说:绝大多数对象都是朝生夕灭
    • 强分代假说:熬过越多次垃圾回收的对象就越难以消亡
    • 跨带引用假说:跨带引用相对于同代引用只占极少数

根据分代收集理论,可以将java堆分为新生代和老年代两部分,在新生代中每次垃圾回收都有大量对象死去,每次回收的幸存者会移动至老年代。这也为后面的垃圾回收算法奠定了基础。

  • 垃圾回收算法:
    • 标记-清除:算法标记需要回收的对象,然后清除,会造成许多内存碎片
    • 标记-整理:与标记-清除算法类似,但是在标记之后,会将活的对象移向另一边,然后清除边界之外的垃圾对象—适用于老年代
    • 标记-复制:将内存分为两块,只使用一块,进行垃圾回收时,先将存活的对象复制到另一块,然后清空之前的区域—使用与年轻代
    • 分代收集:算法将对象分为年轻代和老年代。年轻代每次需回收较多对象,采用标记复制算法。老年代每次回收较少对象,采用标记整理法

8.CMS垃圾回收器(并发收集、低延迟)

在这里插入图片描述

jdk14删除了cms垃圾回收器

9.G1垃圾收集器

在这里插入图片描述

在小内存应用上CMS性能优于G1,大内存应用G1优于CMS,这个优劣势的java堆平衡点通常在6GB-8GB

CMS是追求最短用户停顿时间,无法控制停顿时间,年轻代标记复制,老年代标记清除,会产生较多内存碎片,G1使用多region和rememberSet机制实现了停顿时间可以预测,并且减少了内存碎片

<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()` 使用 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值