Skip to content

Java 垃圾回收机制

TIP

Java 的垃圾回收(GC)自动管理内存,开发者无需手动释放对象。了解 GC 机制有助于写出更高效的程序。

对象存活判定

引用计数法(主流 JVM 不采用)

无法解决循环引用问题。

可达性分析算法(主流)

从 GC Roots 出发,不可达的对象即为可回收对象。

垃圾回收算法

算法描述优缺点
标记-清除标记后直接清除产生内存碎片
复制将存活对象复制到另一区域无碎片,浪费空间
标记-整理标记后整理到一端无碎片,效率较低
分代收集不同代用不同算法综合各种优点

分代回收

java
// JDK8 默认 GC 组合
// 新生代:ParNew(复制算法)
// 老年代:CMS(标记-清除)或 Parallel Old(标记-整理)

// 对象分配规则
// 1. 优先在 Eden 分配
// 2. 大对象直接进入老年代(-XX:PretenureSizeThreshold)
// 3. 长期存活进入老年代(-XX:MaxTenuringThreshold=15)

常用的垃圾回收器

java
// 串行(-XX:+UseSerialGC)
// 适合单核、小内存,暂停时间较长

// 并行(-XX:+UseParallelGC)
// 吞吐量优先,适合后台计算任务

// CMS(-XX:+UseConcMarkSinkMC)
// 低延迟,适合响应式服务,但会产生碎片

// G1(-XX:+UseG1GC)JDK9 默认
// 可预测停顿时间,适合大堆内存

GC 调优参数

bash
# 常用 GC 调优参数
-Xms4g -Xmx4g                    # 堆大小
-Xmn2g                           # 新生代大小
-XX:MetaspaceSize=256m           # 元空间初始大小
-XX:+UseG1GC                     # 使用G1回收器
-XX:MaxGCPauseMillis=100         # 目标最大停顿时间
-XX:+PrintGCDetails              # 打印GC详情
-XX:+HeapDumpOnOutOfMemoryError  # OOM时导出堆转储

常见的 OOM 场景

java
// 1. 堆溢出 - Java heap space
// 原因:对象无法分配到堆内存

// 2. 栈溢出 - StackOverflowError
// 原因:方法调用层级过深(递归无终止条件)

// 3. 元空间溢出 - Metaspace
// 原因:加载了过多类(如动态代理滥用)

TIP

GC 调优的目标通常是在满足停顿时间要求的前提下,提高吞吐量。建议先明确问题(吞吐量低?响应慢?),再针对性调整参数。