新生代(Young Generation) 内部的三个区域

新生代(Young Generation) 内部的三个区域**:Eden 区 和两个 Survivor 区(S0 和 S1)**
默认情况下,JVM 采用 8:1:1 的比例。这意味着如果新生代总共有 100MB 内存,Eden 区占 80MB,两个 Survivor 区各占 10MB。

以下是关于如何调节这个比例以及调节目的的详细说明:
⚙️ 1. 如何调节这个比例?

调节这个比例主要使用 JVM 参数 -XX:SurvivorRatio。

  • 参数含义:该参数定义了 Eden 区 与 其中一个 Survivor 区 的大小比例。
  • 默认值:8(即 Eden:S0:S1 = 8:1:1)。
  • 计算公式:
    • Eden 区占比 = N/(N+2)
    • 每个 Survivor 区占比 = 1/(N+2)
    • (其中 N 为 SurvivorRatio 的值 )

调节示例:

你的需求 设置参数 实际内存分布 (假设新生代 100MB) 说明
默认配置 -XX:SurvivorRatio=8 Eden: 80MB S0: 10MB, S1: 10MB 适合大多数通用应用。
增大 Survivor 区 -XX:SurvivorRatio=4 Eden: 66MB S0: 16.7MB, S1: 16.7MB 适合需要延长对象在新生代停留时间的场景。
增大 Eden 区 -XX:SurvivorRatio=10 Eden: 83MB S0: 8.3MB, S1: 8.3MB 适合绝大多数对象都是"朝生夕死"的场景。
  1. 调节的目的是什么?

调节这个比例的核心目的是在 "减少 GC 频率 " 和 "避免对象过早晋升" 之间找到平衡点。

📉 场景一:调大 Survivor 区(减小 SurvivorRatio,如设为 4 或 6)

  • 目的:防止对象过早晋升到老年代(Premature Promotion)。
  • 原理:如果 Survivor 区太小(比如默认的 10%),当 Eden 区发生 Minor GC 后,存活的对象如果稍微多一点(超过 10%),Survivor 区就装不下了。这些"原本还能在新生代再活几轮"的对象会被直接强制送入老年代。
  • 后果:老年代空间被快速填满,导致触发更耗时的 Full GC。
  • 适用情况:当你发现应用中有很多对象不是"朝生夕死",而是会存活一小段时间,或者 GC 日志显示大量对象直接晋升到老年代时,应调大 Survivor 区(减小参数值)。

⏱️ 场景二:调大 Eden 区(增大 SurvivorRatio,如设为 10 或更高)

  • 目的:降低 Minor GC 的触发频率。
  • 原理:Eden 区越大,能容纳的新对象就越多,填满 Eden 区所需的时间就越长,因此触发 GC 的次数就会减少。
  • 风险:如果 Eden 区过大,留给 Survivor 区的空间就会被压缩。一旦 Eden 区发生 GC,存活对象可能无法放入狭小的 Survivor 区,导致对象直接晋升老年代。
  • 适用情况:如果你的应用中 99% 的对象都是"朝生夕死"(即存活率极低),那么 Survivor 区不需要很大,此时可以增大 Eden 区来提升吞吐量。

📌 总结与建议

调节方向 参数变化 优点 缺点 推荐场景
默认值 SurvivorRatio=8 平衡了 GC 频率和晋升风险。 对特殊场景可能不是最优。 大多数标准 Web 应用。
增大 Survivor SurvivorRatio=4 减少对象进入老年代,降低 Full GC 风险。 Eden 区变小,Minor GC 频率可能略微增加。 对象存活率较高,或发现频繁 Full GC。
增大 Eden SurvivorRatio=10 减少 Minor GC 次数,提升吞吐量。 Survivor 区过小,容易导致对象过早晋升。 对象绝大多数都是"朝生夕死"。

最佳实践:*不要盲目修改这个参数。建议先开启 GC 日志(如 -Xlog:gc),观察 Minor GC 后存活对象的大小 与 Survivor 区大小 的关系。如果 Survivor 区经常被填满导致对象晋升,再考虑调大 Survivor 区(减小 SurvivorRatio)**。

相关推荐
且从容.1 分钟前
JS篇-----
java·javascript·jvm
xiaoqiMikko15 小时前
JVM 线上排查实战(七):jps 看不见它、jstack 连不上它,可它明明活得好好的
java·jvm
用户0942485680316 小时前
第25章:Java虚拟线程(Project Loom)实战与调度协作
java·jvm
wuminyu17 小时前
ForkJoinPool内部WorkQueue的Lock-Free数组操作以及并发任务窃取原理剖析
java·linux·c语言·jvm·c++
墨天梦18 小时前
B10_文件SharedPreferences与SQLite
jvm·数据库·sqlite
EatFan1 天前
2026 Java 后端面试风向变了:八股文只是门槛,场景化追问才是淘汰线
java·开发语言·jvm·面试·后端面试·八股文·full gc
wuminyu2 天前
Virtual Thread重投递至ForkJoinPool任务队列过程解析
java·linux·c语言·jvm·c++
2601_962071573 天前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
用户094248568033 天前
第23章:OpenJDK逃逸分析、标量替换与锁优化
java·jvm
wuminyu3 天前
LockStack在虚拟线程Mount和Unmount拷贝过程剖析
java·linux·c语言·jvm·c++