Files
interview/questions/06-JVM/JVM和垃圾回收.md
yasinshaw 0e46a367c4 refactor: rename files to Chinese and organize by category
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>
2026-03-01 00:10:53 +08:00

325 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# JVM 和垃圾回收
## 问题
1. JVM 内存模型是怎样的?
2. 垃圾回收有哪些算法G1 和 CMS 的区别?
3. 什么是 Stop-The-World如何减少 STW 时间?
4. 常见的 OOM 及解决方案?
5. JVM 参数如何调优?
6. 如何分析 GC 日志?
---
## 标准答案
### 1. JVM 内存模型
#### **运行时数据区**
```
┌─────────────────────────────────────┐
│ 方法区Method Area
│ (类信息、常量、静态变量、JIT 代码) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 堆Heap
│ (对象实例、数组) │
│ ┌──────────┐ ┌──────────┐ │
│ │ 新生代 │ │ 老年代 │ │
│ │ Eden │ │ │ │
│ │ S0 │ │ │ │
│ │ S1 │ │ │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ JVM 栈Java Stack
│ (栈帧:局部变量、操作数栈、返回地址) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 本地方法栈Native Stack
│ (Native 方法调用) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 程序计数器PC Register
│ (当前执行的字节码指令) │
└─────────────────────────────────────┘
```
---
### 2. 垃圾回收算法
#### **标记-清除Mark-Sweep**
**步骤**
1. 标记存活对象
2. 清除未标记对象
**问题**
- 产生内存碎片
- 标记和清除效率都不高
---
#### **复制Copying**
**步骤**
1. 将存活对象复制到另一块内存
2. 清空当前内存
**优点**
- 无内存碎片
- 简单高效
**缺点**
- 内存利用率低(浪费一半)
**适用**新生代Eden + S0 + S1
---
#### **标记-整理Mark-Compact**
**步骤**
1. 标记存活对象
2. 将存活对象向一端移动
3. 清理边界外的内存
**优点**
- 无内存碎片
**缺点**
- 移动对象成本高
**适用**:老年代
---
#### **分代收集Generational**
**原理**
- **弱分代假说**:大多数对象朝生夕灭
- **新生代**复制算法Eden : S0 : S1 = 8 : 1 : 1
- **老年代**:标记-整理或标记-清除
---
### 3. 垃圾收集器
#### **Serial 收集器**
**特点**单线程STW
**适用**:客户端应用、小内存
```bash
-XX:+UseSerialGC
```
---
#### **Parallel 收集器**
**特点**多线程STW
**适用**:后台任务、批处理
```bash
-XX:+UseParallelGC
```
---
#### **CMSConcurrent Mark Sweep**
**特点**:并发收集,低停顿
**步骤**
1. 初始标记STW
2. 并发标记
3. 重新标记STW
4. 并发清除
**问题**
- CPU 敏感
- 浮动垃圾
- 内存碎片
```bash
-XX:+UseConcMarkSweepGC
```
---
#### **G1Garbage First**
**特点**
- **可预测停顿**:用户指定停顿时间
- **分区回收**:将堆划分为多个 Region
- **优先回收垃圾多的 Region**
**适用**:大堆内存(> 6GB、多核 CPU
```bash
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200 # 目标停顿时间
```
---
#### **ZGCZ Garbage Collector**
**特点**
- 并发整理(无内存碎片)
- 停顿时间 < 10ms
- 支持 TB 级堆内存
**适用**:超大内存、低延迟要求
```bash
-XX:+UseZGC
```
---
### 4. OOM 及解决方案
#### **Java.lang.OutOfMemoryError: Java heap space**
**原因**:堆内存不足
**解决**
```bash
# 增加堆内存
-Xms4g -Xmx4g
# 使用 G1 收集器
-XX:+UseG1GC
```
---
#### **Java.lang.OutOfMemoryError: Metaspace**
**原因**:方法区(元空间)不足
**解决**
```bash
# 增加元空间大小
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
```
---
#### **Java.lang.OutOfMemoryError: GC overhead limit exceeded**
**原因**GC 频繁,但回收内存少
**解决**
- 增加堆内存
- 优化代码(减少对象创建)
---
#### **Java.lang.StackOverflowError**
**原因**:栈深度过大(递归太深)
**解决**
```bash
# 增加栈大小
-Xss2m
```
---
### 5. JVM 参数调优
#### **常用参数**
```bash
# 堆内存
-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 等新技术的使用经验