找出 AWS Fargate 上的真实 Java 堆

And*_*ers 5 java docker aws-fargate

我们有一个容器(任务)在 AWS Fargate 中运行,我们看到一些奇怪的行为,其中内存似乎没有正确利用,所以我一直在试图弄清楚它是如何实际设置/使用的......

任务设置为2vCPU/4GB内存。

该应用程序是在 Java 上运行的 Tomcat,Java 的内存设置为 80% ( -XX:MaxRAMPercentage=80.0),但不知何故,Tomcat 似乎将其更改为:

echo $CATALINA_OPTS
-Xms1g -Xmx4g -Djava.security.egd=file:/dev/./urandom
Run Code Online (Sandbox Code Playgroud)

Tomcat/Catalina 因此显示Xmx4g容器的最大容量。4GB内存。

然而,事实证明,试图弄清楚容器中真正使用的是什么有点困难,但要查看容器本身:

root@ip-172-31-28-76:/home/git# java -XX:+PrintFlagsFinal -version | grep HeapSize
   size_t ErgoHeapSizeLimit                        = 0                                         {product} {default}
   size_t HeapSizePerGCThread                      = 43620760                                  {product} {default}
   size_t InitialHeapSize                          = 67108864                                  {product} {ergonomic}
   size_t LargePageHeapSizeThreshold               = 134217728                                 {product} {default}
   size_t MaxHeapSize                              = 1073741824                                {product} {ergonomic}
    uintx NonNMethodCodeHeapSize                   = 5825164                                {pd product} {ergonomic}
    uintx NonProfiledCodeHeapSize                  = 122916538                              {pd product} {ergonomic}
    uintx ProfiledCodeHeapSize                     = 122916538                              {pd product} {ergonomic}
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment 18.9 (build 11.0.13+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8, mixed mode, sharing)
Run Code Online (Sandbox Code Playgroud)

这里看起来是MaxHeapSize(1GB1073741824 字节)

docker stats通过 Fargate 从容器中输出给了我一个Limits.Memory: 4096预期的结果,但内存统计数据很奇怪:

"memory_stats": {
        "usage": 541478912,
        "max_usage": 546689024,
        "stats": {
            "active_anon": 531214336,
            "active_file": 249856,
            "cache": 270336,
            "dirty": 0,
            "hierarchical_memory_limit": 4294967296,
            "hierarchical_memsw_limit": 9223372036854771712,
            "inactive_anon": 0,
            "inactive_file": 3846144,
            "mapped_file": 0,
            "pgfault": 156816,
            "pgmajfault": 0,
            "pgpgin": 149259,
            "pgpgout": 18544,
            "rss": 535040000,
            "rss_huge": 0,
            "total_active_anon": 531214336,
            "total_active_file": 249856,
            "total_cache": 270336,
            "total_dirty": 0,
            "total_inactive_anon": 0,
            "total_inactive_file": 3846144,
            "total_mapped_file": 0,
            "total_pgfault": 156816,
            "total_pgmajfault": 0,
            "total_pgpgin": 149259,
            "total_pgpgout": 18544,
            "total_rss": 535040000,
            "total_rss_huge": 0,
            "total_unevictable": 0,
            "total_writeback": 0,
            "unevictable": 0,
            "writeback": 0
        },
        "limit": 9223372036854771712
    }
Run Code Online (Sandbox Code Playgroud)

这里给出了什么?

“真正的”最大堆是否只有 1GB,如图所示grep HeapSize?

编辑#1:运行 Fargate 统计信息的容器命令curl ${ECS_CONTAINER_METADATA_URI_V4}/stats我可以看到“最大使用内存”实际上是 2.4GB,因此显示的 MaxHeapSize 为 1GB 是不正确的!

编辑#2:经过一些测试后设法让它接受-Xms1g -XX:MaxRAMPercentage=80.0,现在MaxHeapSize显示为 2GB。我已将容器升级到 2vCPU/8GB,但运行的内存统计数据仍然显示使用的最大内存为2.4GB,因此无论设置/更改如何,它使用的内存都不会超过 2.4GB...

Dud*_*Boy 0

建议研究一下元空间的含义。

使用 JVM 选项配置元空间: -XX:MetaspaceSize

建议遵循这个公式:

可用RAM = 512M(用于操作系统)+ 256M(用于Tomcat元空间)+ JVM堆