Organized 50 interview questions into 12 categories: - 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc. - 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理 - 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc. - 04-消息队列 (1 file): RocketMQ/Kafka - 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc. - 06-JVM (1 file): JVM和垃圾回收 - 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc. - 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮 - 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化 - 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx - 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性 - 12-面试技巧 (1 file): 面试技巧和职业规划 All files renamed to Chinese for better accessibility and organized into categorized folders for easier navigation. Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
7.0 KiB
7.0 KiB
JVM 和垃圾回收
问题
- JVM 内存模型是怎样的?
- 垃圾回收有哪些算法?G1 和 CMS 的区别?
- 什么是 Stop-The-World?如何减少 STW 时间?
- 常见的 OOM 及解决方案?
- JVM 参数如何调优?
- 如何分析 GC 日志?
标准答案
1. JVM 内存模型
运行时数据区
┌─────────────────────────────────────┐
│ 方法区(Method Area) │
│ (类信息、常量、静态变量、JIT 代码) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 堆(Heap) │
│ (对象实例、数组) │
│ ┌──────────┐ ┌──────────┐ │
│ │ 新生代 │ │ 老年代 │ │
│ │ Eden │ │ │ │
│ │ S0 │ │ │ │
│ │ S1 │ │ │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ JVM 栈(Java Stack) │
│ (栈帧:局部变量、操作数栈、返回地址) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 本地方法栈(Native Stack) │
│ (Native 方法调用) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 程序计数器(PC Register) │
│ (当前执行的字节码指令) │
└─────────────────────────────────────┘
2. 垃圾回收算法
标记-清除(Mark-Sweep)
步骤:
- 标记存活对象
- 清除未标记对象
问题:
- 产生内存碎片
- 标记和清除效率都不高
复制(Copying)
步骤:
- 将存活对象复制到另一块内存
- 清空当前内存
优点:
- 无内存碎片
- 简单高效
缺点:
- 内存利用率低(浪费一半)
适用:新生代(Eden + S0 + S1)
标记-整理(Mark-Compact)
步骤:
- 标记存活对象
- 将存活对象向一端移动
- 清理边界外的内存
优点:
- 无内存碎片
缺点:
- 移动对象成本高
适用:老年代
分代收集(Generational)
原理:
- 弱分代假说:大多数对象朝生夕灭
- 新生代:复制算法(Eden : S0 : S1 = 8 : 1 : 1)
- 老年代:标记-整理或标记-清除
3. 垃圾收集器
Serial 收集器
特点:单线程,STW
适用:客户端应用、小内存
-XX:+UseSerialGC
Parallel 收集器
特点:多线程,STW
适用:后台任务、批处理
-XX:+UseParallelGC
CMS(Concurrent Mark Sweep)
特点:并发收集,低停顿
步骤:
- 初始标记(STW)
- 并发标记
- 重新标记(STW)
- 并发清除
问题:
- CPU 敏感
- 浮动垃圾
- 内存碎片
-XX:+UseConcMarkSweepGC
G1(Garbage First)
特点:
- 可预测停顿:用户指定停顿时间
- 分区回收:将堆划分为多个 Region
- 优先回收垃圾多的 Region
适用:大堆内存(> 6GB)、多核 CPU
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200 # 目标停顿时间
ZGC(Z Garbage Collector)
特点:
- 并发整理(无内存碎片)
- 停顿时间 < 10ms
- 支持 TB 级堆内存
适用:超大内存、低延迟要求
-XX:+UseZGC
4. OOM 及解决方案
Java.lang.OutOfMemoryError: Java heap space
原因:堆内存不足
解决:
# 增加堆内存
-Xms4g -Xmx4g
# 使用 G1 收集器
-XX:+UseG1GC
Java.lang.OutOfMemoryError: Metaspace
原因:方法区(元空间)不足
解决:
# 增加元空间大小
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
Java.lang.OutOfMemoryError: GC overhead limit exceeded
原因:GC 频繁,但回收内存少
解决:
- 增加堆内存
- 优化代码(减少对象创建)
Java.lang.StackOverflowError
原因:栈深度过大(递归太深)
解决:
# 增加栈大小
-Xss2m
5. JVM 参数调优
常用参数
# 堆内存
-Xms4g # 初始堆大小
-Xmx4g # 最大堆大小
-Xmn2g # 新生代大小
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
# GC 选择
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
# GC 日志
-Xlog:gc*:file=/tmp/gc.log:time,tags:filecount=5,filesize=10m
# OOM 时自动 Dump
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/
调优步骤
1. 监控 GC 频率和停顿时间
2. 分析 GC 日志
3. 调整堆内存和新生代比例
4. 选择合适的 GC 收集器
5. 优化代码(减少对象创建)
6. 压测验证
6. GC 日志分析
工具
- GCViewer:可视化分析
- GCeasy:在线分析(https://gceasy.io)
- 阿里 Arthas:线上诊断
GC 日志示例
[GC (Allocation Failure) [PSYoungGen: 2048K->512K(2560K)] 2048K->1024K(9216K), 0.0023456 secs]
[Full GC (Ergonomics) [PSYoungGen: 512K->0K(2560K)] [ParOldGen: 512K->512K(6656K)] 1024K->512K(9216K), [Metaspace: 5120K->5120K(1056768K)], 0.0234567 secs]
解读:
- GC:Minor GC
- Full GC:Major GC
- Allocation Failure:新生代不足
- Ergonomics:自适应调整
- 2048K->512K(2560K):回收前 2048K,回收后 512K,总容量 2560K
- 0.0023456 secs:停顿时间
7. 阿里 P7 加分项
深度理解:
- 理解 G1 的 Mixed GC 和 Region 设计
- 理解 ZGC 的染色指针和读屏障
- 理解 JVM 的 JIT 编译和逃逸分析
实战经验:
- 有处理线上 OOM 问题的经验
- 有 GC 参数调优的经验
- 有 GC 日志分析和优化经验
架构能力:
- 能设计高吞吐量或低延迟的 JVM 方案
- 能设计 JVM 监控和告警体系
- 能制定 JVM 调优规范
技术选型:
- 了解各种 GC 收集器的适用场景
- 了解 JDK 8/11/17/21 的 GC 改进
- 有 GraalVM 等新技术的使用经验