一、概述
当我们在容器中运行 Java 应用程序时,可能希望对其进行调整参数以充分利用资源。
在本教程中,我们将了解如何在运行 Java 进程的容器中设置 JVM 参数。本文将重点关注常见的 -Xmx 和-Xms 标志。
另外,我们还将研究使用某些 Java 版本运行的程序容器化的常见问题,以及如何在常见的容器化 Java 应用程序时设置自定义标志。
二、Java 容器中的默认堆设置
过去,JVM 不知道分配给容器的内存和 CPU。
Java 10 引入了一个新设置:+UseContainerSupport(默认启用)来修复 这个问题[3],并在 8u191[4] 中将修复反向移植到 Java 8 。
现在 JVM 可以根据分配给容器的内存计算其内存。
1. 自动内存计算
当不设置-Xmx和-Xmx参数时,JVM 会根据系统规格来调整堆大小。
看看堆大小:
$ java -XX:+PrintFlagsFinal -version | grep -Ei "maxheapsize|maxram"
输出结果如下:
openjdk version "15" 2020-09-15 OpenJDK Runtime Environment AdoptOpenJDK (build 15+36) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15+36, mixed mode, sharing) size_t MaxHeapSize = 4253024256 {product} {ergonomic} uint64_t MaxRAM = 137438953472 {pd product} {default} uintx MaxRAMFraction = 4 {product} {default} double MaxRAMPercentage = 25.000000 {product} {default} size_t SoftMaxHeapSize = 4253024256 {manageable} {ergonomic}
我们看到 JVM 将其堆大小设置为可用 RAM 的大约 25%。在这个例子中,在一个 16GB 的系统上分配了 4GB。
出于测试目的,创建一个文件,名为PrintXmxXms.java,内容是以 MB 为单位打印堆大小,代码内容如下:
import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; public class PrintXmxXms { public static void main(String[] args) { int mb = 1024 * 1024; MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); long xmx = memoryBean.getHeapMemoryUsage().getMax() / mb; long xms = memoryBean.getHeapMemoryUsage().getInit() / mb; System.out.println("Initial Memory (xms) : " + xms + "mb"); System.out.println("Max Memory (xmx) : " + xmx + "mb"); } }
假设已经安装了 JDK,可以编译程序并运行:
$ javac ./PrintXmxXms.java $ java -cp . PrintXmxXms