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

......(待续未完

相关推荐
郭涤生2 分钟前
全书测试:《C++性能优化指南》
开发语言·c++·笔记·性能优化
刚正的热带野猪5 分钟前
文件格式校验方案
java·后端
敖正炀9 分钟前
java线程详解
java
Re27512 分钟前
springboot源码分析--初始加载配置类
java·spring boot
五行星辰13 分钟前
SpringBoot集成Log4j2终极指南:从基础配置到性能调优
java·后端
敖正炀16 分钟前
线程之间的通信
java
2401_8670219019 分钟前
C++11·部分重要语法III
开发语言·c++
敖正炀19 分钟前
synchronized加锁解锁流程
java
Fanxt_Ja20 分钟前
【LeetCode】算法详解#2 ---和为k的子数组
java·数据结构·算法·leetcode·idea·哈希表
Thanwind33 分钟前
关于JVM和OS中的栈帧的区别和内存浅析
java·jvm