JVM分代回收

JVM分代回收

新生代

新生代用来存放新创建的对象。大多数对象在这里分配,也大多数会很快被回收。 💡 每次 Minor GC(小型垃圾回收) 都会清理 Eden 区和 From 区,把仍然存活的对象复制到 To 区。然后交换 From 和 To 的角色。


新生代对象的生命周期

🌱 一、对象创建阶段

新对象创建 → 默认分配在 Eden 区(新生代的一部分)。

此时 From、To 两个幸存区(Survivor Spaces)是空的。

🔁 二、第一次 Minor GC 发生

当 Eden 区满了,就会触发一次 Minor GC(小垃圾回收)。

在这次 GC 中:

Eden 区中"存活"的对象(还被引用着的)会被复制到 To 区(Survivor To)。

Eden 区中"无引用"的对象会被直接清理(释放内存)。

这时 From 区其实是空的,因为是第一次 GC,还没有对象被放进去。

可以看到次数标记加1了

✅ 结果:

Eden 区:被清空。

From 区:仍为空。

To 区:保存了"活下来的对象"。

上一次的 To 区 → 变成新的 From 区(存放上次幸存对象)。

另一个空区 → 变成新的 To 区。

在 JVM 的 Minor GC 中,From 区和 To 区(也称为 Survivor 区的两个分区)的切换发生在每次 Minor GC 结束后,而不是下一次 GC 开始前。

🔄 三、第二次及以后的 Minor GC

执行过程:

Eden 区 + From 区 中"还活着"的对象 → 复制到新的 To 区。

其他的对象(无引用的) → 被回收。

GC 完成后,From 区 被清空。

下一次再 GC 时,又会交换 To / From 的角色。

这里如果to里面的对象幸存,要次数加1,图里没标记

🧓 四、晋升(Promotion)

当某个对象在 Survivor 区(From/To)之间多次来回存活(通常是经历 15 次 Minor GC 或达到 JVM 设定阈值), 就会被认为是"老对象",被晋升(Promote)到 老年代(Old Generation)。

老年代

当对象在新生代"活得够久",经历多次 GC 仍然没有被清理,就会被"晋升(Promote)"到老年代。 这里的对象生命周期较长,GC 不会频繁发生,通常由 Major GC(或 Full GC) 清理。

垃圾回收机制对应关系


Minor GC,Major GC,Full GC

Minor GC

当年轻代(Eden区)满时就会触发 Minor GC,这里的年轻代满指的是 Eden区满。Survivor 满不会触发 Minor GC 。

从年轻代空间(主要是 Eden区)回收内存被称为 Minor GC。

发生Minor GC事件需要注意:

  • 当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。

  • 内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。

  • 执行 Minor GC 操作时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。

  • 对于大部分应用程序,Minor GC 操作时应用程序停顿导致的延迟都是可以忽略不计的。因为,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多。

Major GC

CMS收集器中,当老年代满时会触发 Major GC。

目前,只有CMS收集器会有单独收集老年代的行为。其他收集器均无此行为。

针对新生代(主要指Eden区)的Minor GC 比较常见,各个收集器均支持。

通常能单独发生收集行为的只是新生代的Minor GC,所以这里"反过来"的情况只是理论上允许,实际上除了CMS收集器,其他都不存在只针对老年代的收集。(英文翻译过来的,要细品!)

Full GC

Full GC 对收集整堆(新生代、老年代)和方法区的垃圾收集。

当年老代满时会引发Full GC,Full GC将会同时回收新生代、年老代 ; 当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载 。

(1)调用System.gc时,系统建议执行Full GC,但是不一定会执行 。 (2)老年代空间不足 (3)方法区空间不足 (4)通过 Minor GC 后进入老年代的空间大于老年代的可用内存 (5)当对象无法放入 To 区(Survivor Space)时,JVM 会尝试将对象晋升 (Promote) 到老年代。


什么是STW

STW(Stop-The-World) 就是: JVM 在执行某些操作时,会暂停所有用户线程(应用线程),只让 GC 线程(或某些系统线程)工作。 当 STW 发生时:

所有正在运行的 Java 应用代码(业务逻辑线程)都会被 挂起(suspend);

JVM "冻结"整个世界;

GC 或其他内部操作完成后,再让应用线程恢复执行。

触发场景

持续时间

相关推荐
苏三的开发日记13 分钟前
windows系统搭建kafka环境
后端
爬山算法23 分钟前
Netty(19)Netty的性能优化手段有哪些?
java·后端
Tony Bai24 分钟前
Cloudflare 2025 年度报告发布——Go 语言再次“屠榜”API 领域,AI 流量激增!
开发语言·人工智能·后端·golang
想用offer打牌37 分钟前
虚拟内存与寻址方式解析(面试版)
java·后端·面试·系统架构
無量41 分钟前
AQS抽象队列同步器原理与应用
后端
9号达人1 小时前
支付成功订单却没了?MyBatis连接池的坑我踩了
java·后端·面试
用户497357337981 小时前
【轻松掌握通信协议】C#的通信过程与协议实操 | 2024全新
后端
草莓熊Lotso1 小时前
C++11 核心精髓:类新功能、lambda与包装器实战
开发语言·c++·人工智能·经验分享·后端·nginx·asp.net
追逐时光者2 小时前
精选 8 个 .NET 开发实用的类库,效率提升利器!
后端·.net
a程序小傲2 小时前
京东Java面试被问:Fork/Join框架的使用场景
java·开发语言·后端·postgresql·面试·职场和发展