我正在尝试运行一个需要大堆的 Java 应用程序。它在容器内的 AWS ECS 上运行。在具有 128GB RAM 的主机上。该容器已分配 ~115GB。
Dockerfile 基于
eclipse-temurin:11
我正在启动选项
-XX:MaxRAMPercentage=85.0
以及 -XX:+PrintFlagsFinal
来获取反馈。这是我得到的删节内容(对于SO来说太大了)这里有完整的标志https://pastebin.com/jm7Md2c8
2023-01-17 11:02:40 bool MaxFDLimit = true {product} {default}
2023-01-17 11:02:40 uintx MaxGCMinorPauseMillis = 18446744073709551615 {product} {default}
2023-01-17 11:02:40 uintx MaxGCPauseMillis = 200 {product} {default}
2023-01-17 11:02:40 uintx MaxHeapFreeRatio = 70 {manageable} {default}
2023-01-17 11:02:40 size_t MaxHeapSize = 32178700288 {product} {ergonomic}
2023-01-17 11:02:40 intx MaxInlineLevel = 15 {product} {default}
2023-01-17 11:02:40 intx MaxInlineSize = 35 {product} {default}
2023-01-17 11:02:40 size_t MaxMetaspaceExpansion = 5451776 {product} {default}
2023-01-17 11:02:40 uintx MaxMetaspaceFreeRatio = 70 {product} {default}
2023-01-17 11:02:40 size_t MaxMetaspaceSize = 18446744073709547520 {product} {default}
2023-01-17 11:02:40 size_t MaxNewSize = 19306381312 {product} {ergonomic}
2023-01-17 11:02:40 intx MaxNodeLimit = 80000 {C2 product} {default}
2023-01-17 11:02:40 uint64_t MaxRAM = 137438953472 {pd product} {default}
2023-01-17 11:02:40 uintx MaxRAMFraction = 4 {product} {default}
2023-01-17 11:02:40 double MaxRAMPercentage = 85.000000 {product} {command line}
2023-01-17 11:02:40 intx MaxRecursiveInlineLevel = 1 {product} {default}
2023-01-17 11:02:40 uintx MaxTenuringThreshold = 15 {product} {default}
2023-01-17 11:02:40 intx MaxTrivialSize = 6 {product} {default}
2023-01-17 11:02:40 intx MaxVectorSize = 32 {C2 product} {default}
2023-01-17 11:02:40 size_t MetaspaceSize = 21807104 {pd product} {default}
2023-01-17 11:02:40 bool MethodFlushing = true {product} {default}
2023-01-17 11:02:40 size_t MinHeapDeltaBytes = 4194304 {product} {ergonomic}
2023-01-17 11:02:40 uintx MinHeapFreeRatio = 40 {manageable} {default}
2023-01-17 11:02:40 intx MinInliningThreshold = 250 {product} {default}
2023-01-17 11:02:40 intx MinJumpTableSize = 10 {C2 pd product} {default}
2023-01-17 11:02:40 size_t MinMetaspaceExpansion = 339968 {product} {default}
2023-01-17 11:02:40 uintx MinMetaspaceFreeRatio = 40 {product} {default}
2023-01-17 11:02:40 uintx MinRAMFraction = 2 {product} {default}
2023-01-17 11:02:40 double MinRAMPercentage = 50.000000 {product} {default}
2023-01-17 11:02:40 uintx MinSurvivorRatio = 3 {product} {default}
2023-01-17 11:02:40 bool UseContainerSupport = true {product} {default}
所以这似乎是合理的,JVM 检测到主机 ram
MaxRAM = 137438953472
= 128GB,选项 MaxRAMPercentage = 85.000000
已正确设置。 UseContainerSupport = true
所以我的理解是应该应用这些选项。
所以我不明白为什么
MaxHeapSize = 32178700288
只有〜29.9GB?我认为它是分配给容器的 115GB 的 1/4,这似乎意味着我的设置没有被应用,为什么?.
在本地测试
docker run --memory='2g' eclipse-temurin:11 java -XX:MaxRAMPercentage=85.0 -XX:+PrintFlagsFinal -version | grep MaxHeapSize
当改变分配的容器内存和
MaxRAMPercentage
时,似乎可以按预期工作
感谢安德烈。解决方案是添加
-XX:-UseCompressedOops
我刚刚自己解决了这个问题。我正在使用
maven:3-amazoncorretto-17
图像。
我的 Dockerfile 中有以下代码,但 MaxHeapSize 设置为我分配给任务的内存的默认 25%。
ENTRYPOINT java -XX:MaxRAMPercentage=80 -jar build/app.jar
容器启动时,这一点没有得到尊重。为了解决这个问题,我最终使用了
JAVA_TOOL_OPTIONS
。您可以将其放入 Dockerfile 中,也可以在任务定义中添加环境变量。
ENV JAVA_TOOL_OPTIONS="-XX:MaxRAMPercentage=80"
出于调试目的,我按照其中一些步骤通过 SSH 连接到我的容器并运行
java -XshowSettings:vm -version
以确定我的更改是否生效。
sh-4.2# java -XshowSettings:vm -version
Picked up JAVA_TOOL_OPTIONS: -XX:MaxRAMPercentage=80
VM settings:
Max. Heap Size (Estimated): 792.69M
Using VM: OpenJDK 64-Bit Server VM