优化 AWS ECS 的 Java 堆设置

优化 aws ecs 的 java 堆设置

我们在 AWS Elastic Container Service(ECS) Fargate 上运行多个 Java 服务 (Corretto JDK21)。每个服务都有自己的容器,我们希望使用为每个进程支付的所有可能的资源。但这些步骤可以应用于 EC2 和其他云。

服务正在运行批处理作业,延迟并不重要,我们使用并行GC(-XX:+UseParallelGC)。即使完成我们的任务,也许 G1 会更好,但这是一个需要单独研究和发布的主题。
为了使用所有可用内存,我们的 MaxHeapSize 略低于容器内存大小。但一段时间后,我们注意到两个问题,有时我们的容器因为使用太多内存而被杀死,有时我们收到 OutOfMemoryError 异常。 为了解决第一个问题,我们增加了容器内存大小和 MaxHeapSize 之间的差距,对于第二个问题,增加了容器内存作为快速解决方案,并开始查看堆转储。

堆转储显示了有趣的细节,实际堆大小低于 MaxHeapSize,并且与老一代相比,年轻代堆很小。

在互联网上搜索并没有找到关于如何针对我们的案例调整 JVM 参数的良好指南,我只找到了一些有关堆和参数描述的高级详细信息。我决定写这篇文章来描述我所做的步骤。

第一步是:

堆友 堆友

Alibaba Design打造的设计师全成长周期服务平台,旨在成为设计师的好朋友

堆友 306 查看详情 堆友

立即学习“Java免费学习笔记(深入)”;

打印有关参数和默认值的信息:(-XX:+PrintFlagsFinal),将InitialHeapSize设置为与MaxHeapSize相同的值(-XX:InitialRAMPercentage=100或仅将-XX:InitialHeapSize设置为与MaxHeapSize相同的值)。无论如何,我们都在为所有容器内存付费,所以为什么不从一开始就分配它呢?记录 GC 和堆信息 (-Xlog:gc*)。

Young:Old Generation默认比例为1:2,同时只使用部分Young Generation进行GC。启动后,JVM 按预期分配了所有内存,但一段时间后,它开始将年轻代堆大小减少到几乎几兆字节。所以一段时间后我们只使用了 2/3 的可用内存。
经过一番挖掘,我发现了一个禁用自适应策略的参数(-XX:-UseAdaptiveSizePolicy),它有所帮助,堆停止减少,垃圾收集之间的间隔增加了一个数量级甚至更多。 GC 消耗的时间也有所增长,但增幅不大。

下一步是找到容器内存大小之间的最佳差距。默认情况下,即使InitialRAMPercentage=100,JDK也只是分配内存而不使用它,因此它不会被映射。 Linux 允许分配比物理内存更多的虚拟内存。当内存实际映射(JDK 写入它)时,容器稍后会失败。 -XX:+AlwaysPreTouch 更改此行为。不幸的是,有些内存仍然没有映射,但 OOM 终止发生得更快。经过几次尝试后,我得出了下一个公式“容器内存大小 – 1024MB”(对于具有 8GB 或更多内存的容器)。例如,对于 8192 容器内存大小,我们使用 -XX:MaxHeapSize=7168m。

为了进一步优化,我们正在考虑更改 -XX:NewRatio 以减少年轻代大小并减少 GC 时间。但这取决于对象在应用程序中的生命周期。
正如我之前提到的,我还没有找到任何好的指南来详细解释参数(我发现最好的是 vm-options-explorer)和调整步骤。如果您能分享您的知识和成果,那就太好了。

以上就是优化 AWS ECS 的 Java 堆设置的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/471365.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 07:38:23
下一篇 2025年11月8日 07:38:55

相关推荐

发表回复

登录后才能评论
关注微信