JVM - 年轻代和老年代

通过一些问题来讨论 JVM 中年轻代和老年代的内容

  • 为什么要区分年轻代和老年代?
  • 哪些对像会进入老年代?
  • 什么时候会进行年轻代GC?
  • 什么时候会进行老年代GC?

1. 为什么要区分年轻代和老年代?

年轻代中的对象大部分都是短期存活的,老年代中的对象存活时间较长

而短期存活的对象,很快就会被垃圾回收线程回收。

考虑到两部分对象的垃圾回收时机不同,所以就要将其区分

年轻代有年轻代的垃圾回收算法,老年代有老年代的垃圾回收算法,"因地制宜"

2. 哪些对象会进入老年代

我们分为 Young GC 之前和 Young GC 来说

Young GC之前,如果加入堆内存的对象足够大,则直接进入老年代,可通过 JVM 参数 "-XX:PretenureSizeThreshold" 来设置这个值,单位是字节

比如 "-XX:PretenureSizeThreshold" 的值设为 "1048576" 字节,而你创建了一个大小大于这个数的对象,比如一个超大的数组,此时就直接将这个大对象放到老年代里去

Young GC 之后,则有多种情况

如果对象已经经历了15次 GC,即对象年龄已经达到 15,则会被转移到老年代

还有一种动态对象年龄判断,不需要对象年龄达到 15 也可以进入老年代。大致规则就是,假设当前放对象的 Survivor 区中,有一批对象的总大小大于了这块区域的 50%,则所有年龄大于等于这批对象年龄的对象,都可以直接进入老年代

无论是年龄大于 15,还是动态对象年龄判断,都是为了那些可以长期存活的对象尽早地进入到老年代

还有,如果 GC 过后,存活对象的大小大于 Survivor 可用空间,则这些对象也会直接进入到老年代

3. 什么时候会进行年轻代 GC

这里年轻代 GC,认为是 Young GC

当年轻代中的 Eden 区中区域不够用时,则会触发年轻代 GC

4. 什么时候会进行老年代 GC

这里老年代 GC,认为是 Full GC

每一次 Minor GC 之前,会检查老年代老年代可用空间是否大于年轻代所有对象大小,因为可能 GC 之后,所有的年轻代对象都存活下来了。如果小于的话,则还要判断是否打开了 "-XX:-HandlePromotionFailure"的参数设置

如果没打开这个参数,则直接进行 Full GC

否则打开了的话, 则就看老年代内存大小,是否大于之前每一次 Minor GC 后进入老年代对象的平均大小。小于的话,则会进行 Full GC

这是 Minor GC 之前做的判断。

如果 Minor GC 之后,存活对象大小大于 Survivor 可用空间,也大于老年代可用空间,也会进行 Full GC



诚恳欢迎大家提出意见Orz

......(待续未完

相关推荐
YDS8291 分钟前
DeepSeek RAG&MCP + Agent智能体项目 —— 环境搭建和项目初始化
java·springboot·agent·rag·deepseek
会编程的土豆1 分钟前
Go ini 配置加载:`ini.MapTo` 详细解析
开发语言·数据库·golang
ChoSeitaku2 分钟前
04.数组
java·开发语言·数据结构
float_com5 分钟前
【java进阶】------ 多线程【实际案例分析】
java
用户298698530145 分钟前
Java 中的 Word 变量管理:添加、统计、获取与删除
java·后端
techdashen9 分钟前
半小时读懂 Rust:从语法符号到所有权思维
开发语言·rust
郭龙_Jack11 分钟前
Java 17 到 Java 25:LTS 升级的全面收益与迁移指南
java·开发语言·python
2301_8092445314 分钟前
mysql如何处理大量重复值索引_mysql索引存储特征分析.txt
jvm·数据库·python
要开心吖ZSH16 分钟前
Java AI Agent 开发中的 RAG 实现方案及小白入门指南
java·ai·agent·rag
掉鱼的猫16 分钟前
Java 流程编排新范式 Solon Flow:一个引擎,七种节点,覆盖规则/任务/工作流/AI 编排全场景
java·workflow