为 Azure 容器应用中的 Java 应用高效使用内存
Java 虚拟机 (JVM) 保守地使用内存,因为它假设操作系统内存必须在多个应用程序之间共享。 但是,你的容器应用可以优化内存使用情况,并为应用提供尽可能多的可用内存。 此内存优化称为 Java 自动内存拟合。 启用内存调整后,Java 应用性能通常会提高 10% 到 20%,而无需更改任何代码。
Azure 容器应用在以下情况下支持自动内存拟合:
- 单个 Java 应用在容器中运行。
- 应用程序部署自源代码或 JAR 文件。
默认情况下启用自动内存拟合,但可以手动禁用。
禁用内存拟合
大多数情况下,自动内存拟合非常有用,但这可能并非适用于所有情况。 可以手动或自动禁用内存拟合。
手动禁用
若要在创建容器应用时禁用内存拟合,请将环境变量 BP_JVM_FIT
设置为 false
。
以下示例演示了如何通过 create
、up
和 update
命令禁用内存拟合。
az containerapp create \
--name <CONTAINER_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--image <CONTAINER_IMAGE_LOCATION> \
--environment <ENVIRONMENT_NAME> \
--env-vars BP_JVM_FIT="false"
若要验证是否已禁用内存拟合,请检查日志中是否有以下消息:
禁用 jvm 内存拟合,原因:手动禁用
自动禁用
满足以下任一条件时,系统会自动禁用内存拟合:
容器内存有限:容器内存小于 1 GB。
明确设置内存选项:通过
JAVA_TOOL_OPTIONS
在环境变量中指定一项或多项内存设置时。 内存设置选项包括以下值:-XX:MaxRAMPercentage
-XX:MinRAMPercentage
-XX:InitialRAMPercentage
-XX:MaxMetaspaceSize
-XX:MetaspaceSize
-XX:ReservedCodeCacheSize
-XX:MaxDirectMemorySize
-Xmx
-Xms
-Xss
例如,如果已在环境变量中指定最大堆大小,则会自动禁用内存拟合,如下例所示:
az containerapp update \ --name <CONTAINER_APP_NAME> \ --resource-group <RESOURCE_GROUP> \ --image <CONTAINER_IMAGE_LOCATION> \ --set-env-vars JAVA_TOOL_OPTIONS="-Xmx512m"
禁用内存拟合后,会在记录中看到以下消息输出:
禁用 jvm 内存拟合,原因:使用 JAVA_TOOL_OPTIONS=-Xmx512m 中指定的设置,而不是选取 JAVA_TOOL_OPTIONS: -Xmx512m
小型非堆内存大小:在极少数情况下,计算出的堆或非堆大小太小(小于 200 MB)。
验证是否已启用内存
在启动期间检查日志流中是否存在引用计算的 JVM 内存配置的消息。
下面是启动期间的消息输出示例。
计算的 JVM 内存配置:-XX:MaxDirectMemorySize=10M -Xmx1498277K -XX:MaxMetaspaceSize=86874K -XX:ReservedCodeCacheSize=240M -Xss1M(总内存:2G,线程计数:250,已加载类计数:12924,空余空间:0%)
选取 JAVA_TOOL_OPTIONS:-XX:MaxDirectMemorySize=10M -Xmx1498277K -XX:MaxMetaspaceSize=86874K -XX:ReservedCodeCacheSize=240M -Xss1M
运行时配置
可以设置环境变量以影响内存拟合行为。
变量 | Unit | 示例 | 说明 |
---|---|---|---|
BPL_JVM_HEAD_ROOM |
百分比 | BPL_JVM_HEAD_ROOM=5 |
根据给定的百分比为系统保留内存空间。 |
BPL_JVM_THREAD_COUNT |
Number | BPL_JVM_THREAD_COUNT=200 |
预估的最大线程数。 |
BPL_JVM_CLASS_ADJUSTMENT |
Number 百分比 |
BPL_JVM_CLASS_ADJUSTMENT=10000 BPL_JVM_CLASS_ADJUSTMENT="10%" |
按明确值或百分比调整 JVM 类计数。 |
注意
更改这些变量不会禁用自动内存拟合。
内存不足警告
如果你决定自行配置内存设置,则可能会遇到内存不足警告的风险。
下面是容器可能耗尽内存的一些可能原因:
堆内存大于可用内存总量。
非堆内存大于可用内存总量。
堆 + 非堆内存大于可用内存总量。
在容器内存不足的情况下会遇到以下警告:
OOM 警告:堆内存 1200M 大于可用于分配 (-Xmx1200M) 的 1G 大小