在了解 JVM之前,给大家推荐一个工具,阿里开源的 Arthas 。官网地址: arthas 。 这个工具功能非常强大,是对 Java进程进行性能调优的一个非常重要的工具,对于了解 JVM 底层帮助也非常大。
一、垃圾回收器核心定义
1.1 什么是GC垃圾回收器?
通俗一句话定义:GC 是 JVM 自带的自动内存清理工具,专门用来回收程序中「没有任何引用、不再使用的无效对象」,自动释放堆内存,避免内存溢出、内存泄漏。
写 Java 不需要像 C/C++ 一样手动申请、释放内存,核心就是依靠 GC 自动管理内存。
GC 的核心工作只有两件事:
-
标记:找出内存中哪些对象是垃圾、哪些是存活对象
-
清除:回收无效垃圾对象,腾空内存空间
核心目标:保证内存高效利用、避免内存溢出、保障程序稳定长期运行。
二、JVM内存布局(GC的工作场地)
想要学懂 GC,必须先搞懂 GC 到底在哪工作。GC 不是全内存回收,只针对线程共享的动态内存区域工作,线程私有区域几乎不参与GC回收。
2.1 完整内存布局划分(JDK8标准)
JVM 运行时数据区分为两大板块:线程私有内存、线程共享内存。
1. 线程私有区域(无GC、无需垃圾回收)
生命周期和线程绑定,线程创建则创建,线程销毁则自动释放,无需GC干预:
-
程序计数器:记录代码执行位置,空间极小,无GC、无OOM
-
虚拟机栈:存储方法栈帧、局部变量,线程结束自动释放
-
本地方法栈:服务native底层方法,随线程销毁释放
2. 线程共享区域(GC核心工作区)

全局共享、长期驻留、动态创建对象,是GC唯一的工作范围:
-
堆内存(Heap) :GC主战场 ,所有new对象、数组全部存在这里,99%的垃圾回收都发生在堆,他的大小可以由参数 -Xms(初始堆内存大小), -Xmx(最大堆内存)参数指令。
-
元空间(Metaspace):JDK8替代永久代,存储类元数据、静态信息,极少触发GC
2.2 布局核心总结(GC关键结论)
GC 只管堆内存!
栈内存、程序计数器完全不用GC,线程结束自动释放。所有GC调优、GC卡顿、垃圾回收问题,全部聚焦在堆内存。
三、分代收集模型(GC核心设计思想)
3.1 为什么需要分代?
JVM 通过大量统计发现:
JAVA做过统计, 80%的对象都是"朝生夕死" 。这些对象,被集中放在了一块比较小的内存空间当中,快速创建,快速回收,这块内存区域就是年轻代。在年轻代会非常频繁的进行垃圾回收,称为YoungGC。而年轻代又会被进一步划分为一个eden_space和两个survivor。这三个区域的大小比例默认是 8:1:1。
另外少部分需要长期使用的对象,被放到另一块竞争没有那么激烈的对象,则被放到另外一块比较大的内存空间当中,长期保持,这块内存就是老年代。在老年代,垃圾回收的频率则会相对比较低,只有空间不够时才进行,称为OldGC。
年轻代与老年代默认的大小比例是 1:2。
常见的分代收集模型中,对象会优先在eden区创建,经过一次YoungGC后,如果没有被回收,就会被移动到一个survivor区。接下来,下一次YoungGC时,又会被移动到另一块Survivor区。每移动一次,记录一个分代年龄。直到分代年龄太大了(默认是16),就会被移动到老年代。到老年代后,对象就不再记录分代年龄了,在老年代安安静静的用到退休。
这就是JDK最有代表性的分代年龄收集机制。通过分代收集机制, JVM可以对不同的对象采取不同的回收策略,从而提高垃圾回收的效率。
如果所有对象统一回收,效率极低、浪费性能。所以 JVM 把堆内存按对象存活时间分代,不同代采用不同回收策略,大幅提升GC效率。
3.2 堆内存分代结构(JDK8通用)
堆内存整体分为两大代:新生代 + 老年代

1. 新生代(Young Generation)
存放刚创建、短期存活的临时对象,占堆内存 1/3。
内部细分三块:Eden区 + Survive0 + Survive1
-
Eden区:对象新建的默认区域,占新生代80%空间
-
两个Survivor区:大小相等、轮换使用,用于存活对象转移
特点:对象消亡快、回收频率高、回收速度快。
2. 老年代(Old Generation)
存放长期存活、年龄较大、体积较大的对象,占堆内存 2/3。
经过多次新生代GC依然存活的对象,会晋升到老年代。
特点:对象存活久、回收频率低、单次回收耗时更长。
3.3 分代收集工作机制(完整流程)
全程大白话串联对象的一生,看懂就彻底懂分代GC:
-
对象创建:所有新对象优先在 Eden 区诞生
-
新生代GC(Minor GC):Eden区满了触发Minor GC,快速清理所有垃圾对象;存活对象移入空闲的Survivor区,年龄+1
-
年龄晋升:对象反复躲过多次Minor GC,年龄达到阈值(默认15),晋升到老年代;大对象直接进入老年代
-
老年代GC(Major GC/Full GC):老年代空间不足时触发,回收老年代垃圾,速度慢、耗时久、尽量避免频繁触发
核心优势:短命对象快速清理、长命对象少扫描,精准适配对象生命周期,最大化GC效率。
四、JVM主流垃圾回收器大全(JDK8生产常用)
分代模型是底层设计,回收器是具体干活的工具。不同回收器,对应不同回收算法、性能、适用场景。java 从诞生到现在最新的 JDK21版本,总共就产生了以下十个垃圾回收器

JDK8 主流四大回收器,按使用场景、性能优先级排序:
4.1 Serial 串行回收器(单线程)
-
工作方式:单线程回收,回收时暂停所有业务线程(STW)
-
特点:简单、内存占用小、无多线程竞争、卡顿严重
-
适用场景:客户端程序、单机小项目、测试环境,生产基本不用
4.2 Parallel 并行回收器(JDK8默认)
-
工作方式:多线程并行GC,依旧存在STW,优先追求高吞吐量
-
特点:回收速度快、吞吐量高、适合后台任务、对延迟不敏感
-
适用场景:普通后台业务、批量任务、非核心高并发服务
4.3 CMS 并发回收器(经典低延迟)
-
工作方式:大部分阶段和业务线程并发执行,减少STW停顿时间
-
特点:低延迟、卡顿小、吞吐量略低、内存碎片多
-
适用场景:需要快速响应、低延迟的核心业务(订单、支付、用户服务)
-
备注:JDK9开始废弃,JDK8为最后稳定可用版本
4.4 G1 垃圾回收器(高性能全能型)
-
工作方式:摒弃传统分代固定划分,采用分区回收,可灵活控制停顿时间
-
特点:兼顾吞吐量与低延迟、可预测卡顿、自动整理内存碎片
-
适用场景:大内存、高并发、高性能、核心生产集群
-
备注:JDK9+默认回收器,JDK8可手动开启,是目前主流升级方案
4.5 回收器选型极简总结(生产直接用)
-
小项目、测试环境 → Parallel
-
核心低延迟业务 → CMS
-
大内存、高并发、追求稳定 → G1
五、GC实战分析:运行参数、日志参数、日志解读
理论学完,重点落地实战!线上排查GC卡顿、OOM问题,全靠JVM参数+GC日志分析。
5.1 常见GC运行参数(JDK8生产标配)
分为内存参数、GC类型参数、日志输出参数三类,全部是生产常用参数:
1. 核心内存参数
-
-Xms:JVM初始堆内存(生产建议与最大堆一致,避免动态扩容) -
-Xmx:JVM最大堆内存(防止堆溢出) -
-Xmn:新生代内存大小,单独控制年轻代空间 -
-XX:MaxMetaspaceSize:元空间最大限制,防止元数据溢出
2. 回收器选型参数
-
-XX:+UseParallelGC:开启Parallel并行回收器(默认) -
-XX:+UseConcMarkSweepGC:开启CMS低延迟回收器 -
-XX:+UseG1GC:开启G1全能回收器
3. 辅助调优参数
-
-XX:MaxGCPauseMillis:限制GC最大停顿时间(G1核心参数) -
-XX:+PrintGCDetails:打印GC详细日志 -
-XX:+PrintGCTimeStamps:打印GC时间戳
5.2 常用GC日志输出参数
线上排查问题必须开启日志,核心参数:
-
-XX:+PrintGC: 打印GC信息 类似于-verbose:gc
-
-XX:+PrintGCDetails:输出GC详细信息(内存变化、耗时、代区回收情况) -
-XX:+PrintGCTimeStamps:配合 -XX:+PrintGC使用。在 GC 中打印时间戳。 -
-XX:PrintHeapAtGC: 打印GC前后的堆栈信息
-
-XX:+PrintGCApplicationStoppedTime:打印STW停顿时间 -
-Xloggc:/xxx/gc.log:指定GC日志输出路径,持久化保存
5.3 实战GC日志分析(零基础秒懂)
我们以最常见的 Minor GC 日志 举例,手把手教你读懂日志核心信息:
示例日志:
GC (Allocation Failure) [Eden: 20480K->1024K(22528K), 0.012s] 20480K->2048K(81920K), 0.015s]
逐段通俗解读:
-
Allocation Failure:内存分配失败,Eden区已满,触发新生代GC -
Eden:20480K->1024K:Eden区原有20M内存,回收后只剩1M存活对象 -
22528K:Eden区总容量 -
0.012s:新生代GC耗时12毫秒 -
20480K->2048K(81920K):整体堆内存从20M回收至2M,堆总容量80M -
0.015s:本次GC总耗时15毫秒
5.4 日志排查核心结论(实战刚需)
-
频繁Minor GC:新生代内存过小、短命对象过多,需调大新生代空间
-
频繁Full GC:老年代内存不足、内存泄漏、大对象过多,严重影响性能
-
GC耗时持续走高:堆内存过大、回收器选型不合适,需更换低延迟回收器
六、全文串联总结
整篇文章逻辑闭环,层层关联一键梳理:
-
GC定义:JVM自动垃圾回收工具,标记+清除无效对象,自动管理堆内存
-
内存布局:GC只针对堆内存,栈内存无需回收;堆分新生代、老年代两大区域
-
分代模型:适配对象朝生夕灭特性,新生代高频轻量回收、老年代低频重量级回收
-
工作机制:对象诞生于Eden -> 存活进入Survivor -> 年龄达标晋升老年代 -> 空间不足触发GC回收
-
回收器选型:Parallel追求吞吐量、CMS追求低延迟、G1兼顾全能稳定
-
GC实战:通过JVM参数配置内存与回收器,通过GC日志分析内存状态、排查性能问题