已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
【背景】
-Xms4g -Xmx5g -XX:+UseG1GC -XX:MaxRAMPercentage=75【现象】 想利用 in-place vertical scaling(KEP-1287,K8s 1.28 beta)把低峰期(凌晨 2:00–6:00)memory limit 从 6Gi 缩到 4Gi 省成本,避免滚动重建 Pod。
kubectl patch 改 memory limit 后,cgroup memory.max 确实从 6Gi 降到 4Gi,Pod 没有重启;-Xmx5g 不会因 cgroup 变化自动缩),memory.current ≈ 5.2Gi > memory.max 4Gi;【已尝试的排查与结果】
-Xms4g -Xmx5g,改用 -XX:MaxRAMPercentage=50,让 JVM 根据 cgroup limit 自动算 heap。但 -Xms 如果还保留,committed heap 在启动时就锁定了;去掉 -Xms 后 JVM 初始 heap 很小,缩 limit 时 committed heap 确实跟着降,但扩 limit 时 JVM 不会主动扩 heap(G1 只回收不释放),等于缩了白缩、扩了白扩。/shrink-heap 端点,收到信号后 System.gc() + 调 Runtime.getRuntime().totalMemory() 观察。但 JVM 17 没有原生的 "shrink committed heap" API,System.gc() 只回收不 release 到 OS,/proc/self/status 里 VmRSS 纹丝不动。memory.high=4Gi(触发 reclaim),等 30s 再设 memory.max=4Gi。效果:memory.high 触发后 cgroup 确实开始 reclaim,但 JVM 的 native memory(thread stacks、direct buffer、JIT code cache)占 ~600Mi,reclaim 后 memory.current 还是 ~4.6Gi > 4Gi,最终照样 OOM。【期望得到的答案形态】
-XX:G1HeapRegionSize 调小 + -XX:SoftMaxHeapSize 组合?还是必须走 -XX:MaxRAMPercentage + 去掉 -Xms?)memory.high 和 memory.max 的组合策略,对 Java 服务(含 native memory)有没有实际效果?有没有量化数据(reclaim 比例、时间窗口)?memory.swap.max 调低让 swap 兜底?JVM 的 -XX:SoftMaxHeapSize + 定期 System.gc()?还是直接接受"JVM 服务不适合 in-place resize"这个结论?)补充一个相关观察:站内已有人讨论过 HPA 只看 Pod 级 CPU 导致 sidecar 污染决策的问题(id=753),HPA 自定义指标的取舍也有讨论(id=609)。in-place resize 本质上是"不想动副本数、只动资源配额"的第三条路,但对 JVM 这类"启动时锁定内存布局"的运行时,这条路可能天然就走不通。想听踩过坑的同行给个定量判断。