Eden 和 Survivor 比例可以调整么,参数是什么?还用到了哪些参数?
Git高速下载
程序员面试资料大全|各种技术书籍等资料-1000G
一、Eden 与 Survivor 比例调整
1. 核心参数:
-XX:SurvivorRatio=N
定义:Eden 区大小
与 单个 Survivor 区大小的比例(默认值 8)
计算公式:
示例:Eden = (Ratio / (Ratio + 2)) * YoungGen Survivor = (1 / (Ratio + 2)) * YoungGen (每个 Survivor 区)
-XX:SurvivorRatio=8 # Eden : Survivor0 : Survivor1 = 8:1:1 -XX:SurvivorRatio=4 # Eden : Survivor0 : Survivor1 = 4:1:1(Eden 占比减小)
2. 验证设置生效:
jinfo -flag SurvivorRatio <pid> # 查看当前比例
jstat -gc <pid> # 观察 EU(eden) / SU(survivor) 实际大小
二、年轻代关键参数大全
参数 | 作用 | 默认值 |
---|---|---|
-XX:NewRatio=N | 老年代与年轻代的大小比(OldGen:YoungGen = N:1 ) | JDK8: 2 |
-Xmn<size> | 直接设置年轻代总大小(优先级高于 NewRatio ) | 无 |
-XX:InitialSurvivorRatio=N | 初始 Survivor 比例(通常被 SurvivorRatio 覆盖) | 8 |
-XX:+UseAdaptiveSizePolicy | 开启自适应大小策略(动态调整 Eden/Survivor) | ParallelGC 开启 |
-XX:TargetSurvivorRatio=N | Survivor 区目标使用率(影响对象晋升年龄) | 50(百分比) |
-XX:MaxTenuringThreshold=N | 对象晋升老年代的年龄阈值 | 15 |
-XX:+NeverTenure | 对象永不晋升老年代(Survivor 不足直接 OOM) | 关闭 |
-XX:+AlwaysTenure | 对象在第一次 Minor GC 后直接进入老年代 | 关闭 |
三、配置示例与原理
场景:优化短生命周期对象应用(如 Web 服务)
-Xmn1.5g # 年轻代固定 1.5GB
-XX:SurvivorRatio=6 # Eden 占 6/8=75%,每个 Survivor 占 12.5%
-XX:TargetSurvivorRatio=90 # 允许 Survivor 使用到 90%(避免浪费空间)
-XX:MaxTenuringThreshold=6 # 降低晋升阈值,加速回收
内存分配效果:
年轻代总量 = 1536 MB- Eden = (6/(6+2)) * 1536 = 1152 MB- Survivor0 = 192 MB- Survivor1 = 192 MB
四、调优注意事项
-
Survivor 空间不足的后果:
- 对象直接晋升老年代 → 老年代碎片化 + 提前触发 Full GC
- 解决方案:增大
-XX:SurvivorRatio
或 整体扩大年轻代 (-Xmn
)
-
自适应策略的干扰:
- 若开启
-XX:+UseAdaptiveSizePolicy
(ParallelGC 默认开启),JVM 会动态覆盖SurvivorRatio
- 需关闭自适应以固定比例:
-XX:-UseAdaptiveSizePolicy # 关闭自适应
- 若开启
-
G1 收集器的差异:
- G1 没有
SurvivorRatio
概念! - 通过分区(Region)自动管理,需调整目标暂停时间:
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 # 控制 GC 最大停顿时间
- G1 没有
五、监控与验证手段
-
GC 日志分析:
-Xlog:gc*,gc+age=trace:file=gc.log # JDK9+ 打印对象年龄分布
- 关注日志中的
Desired survivor size
和new threshold
(动态晋升阈值)
- 关注日志中的
-
jstat 实时观测:
jstat -gcutil -t <pid> 1000 # 每秒输出各区域使用率
输出关键列:
YGC
:Young GC 次数YGCT
:Young GC 总耗时S0
/S1
:Survivor 区使用率TT
(Tenuring Threshold):当前晋升阈值MTT
(Max Tenuring Threshold):最大晋升阈值
-
堆转储分析:
jmap -dump:live,format=b,file=heap.hprof <pid>
用 Eclipse MAT 分析对象年龄分布:
// 查看对象在年轻代的滞留时间 Objects -> Group By -> Object Age (Generations)
六、经验性调优建议
场景 | 策略 |
---|---|
短生命周期对象居多 | 增大 Eden 比例(-XX:SurvivorRatio=10~12 ),降低晋升阈值(-XX:MaxTenuringThreshold=3~5 ) |
存在中等生命周期对象 | 扩大 Survivor 区(-XX:SurvivorRatio=4~6 ),提高 TargetSurvivorRatio=70~90 |
频繁发生过早晋升 | 检查 Survivor 是否过小 → 增大 -Xmn 或 调整 SurvivorRatio |
CMS/G1 老年代碎片严重 | 降低晋升速度 → 增大 -XX:MaxTenuringThreshold 或 扩大 Survivor |
程序员面试资料大全|各种技术书籍等资料-1000G
Git高速下载