Use memory efficiently for Java apps in Azure Container Apps (preview)
The Java Virtual Machine (JVM) uses memory conservatively as it assumes OS memory must be shared among multiple applications. However, your container app can optimize memory usage and make the maximum amount of memory possible available to your application. This memory optimization is known as Java automatic memory fitting. When memory fitting is enabled, Java application performance is typically improved between 10% and 20% without any code changes.
Azure Container Apps provides automatic memory fitting under the following circumstances:
- A single Java application is running in a container.
- Your application is deployed from source code or a JAR file.
Automatic memory fitting is enabled by default, but you can disable manually.
Disable memory fitting
Automatic memory fitting is helpful in most scenarios, but it might not be ideal for all situations. You can disable memory fitting manually or automatically.
Manual disable
To disable memory fitting when you create your container app, set the environment variable BP_JVM_FIT
to false
.
The following examples show you how to use disable memory fitting with the create
, up
, and update
commands.
az containerapp create \
--name <CONTAINER_APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--image <CONTAINER_IMAGE_LOCATION> \
--environment <ENVIRONMENT_NAME> \
--env-vars BP_JVM_FIT="false"
To verify that memory fitting is disabled, check your logs for the following message:
Disabling jvm memory fitting, reason: manually disabled
Automatic disable
Memory fitting is automatically disabled when any of the following conditions are met:
Limited container memory: Container memory is less than 1 GB.
Explicitly set memory options: When one or more memory settings are specified in environment variables through
JAVA_TOOL_OPTIONS
. Memory setting options include the following values:-XX:MaxRAMPercentage
-XX:MinRAMPercentage
-XX:InitialRAMPercentage
-XX:MaxMetaspaceSize
-XX:MetaspaceSize
-XX:ReservedCodeCacheSize
-XX:MaxDirectMemorySize
-Xmx
-Xms
-Xss
For example, memory fitting is automatically disabled if you specify the maximum heap size in an environment variable like shown the following example:
az containerapp update \ --name <CONTAINER_APP_NAME> \ --resource-group <RESOURCE_GROUP> \ --image <CONTAINER_IMAGE_LOCATION> \ --set-env-vars JAVA_TOOL_OPTIONS="-Xmx512m"
With memory fitting disabled, you see the following message output to the log:
Disabling jvm memory fitting, reason: use settings specified in JAVA_TOOL_OPTIONS=-Xmx512m instead Picked up JAVA_TOOL_OPTIONS: -Xmx512m
Small non-heap memory size: Rare cases when the calculated size of heap or nonheap size is too small (less than 200 MB).
Verify memory fit is enabled
Inspect your log stream during start-up for a message that references Calculated JVM Memory Configuration.
Here's an example message output during start-up.
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx1498277K -XX:MaxMetaspaceSize=86874K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 2G, Thread Count: 250, Loaded Class Count: 12924, Headroom: 0%)
Picked up JAVA_TOOL_OPTIONS: -XX:MaxDirectMemorySize=10M -Xmx1498277K -XX:MaxMetaspaceSize=86874K -XX:ReservedCodeCacheSize=240M -Xss1M
Runtime configuration
You can set environment variables to affect the memory fitting behavior.
Variable | Unit | Example | Description |
---|---|---|---|
BPL_JVM_HEAD_ROOM |
Percentage | BPL_JVM_HEAD_ROOM=5 |
Leave memory space for the system based on the given percentage. |
BPL_JVM_THREAD_COUNT |
Number | BPL_JVM_THREAD_COUNT=200 |
The estimated maximum number of threads. |
BPL_JVM_CLASS_ADJUSTMENT |
Number Percentage |
BPL_JVM_CLASS_ADJUSTMENT=10000 BPL_JVM_CLASS_ADJUSTMENT="10%" |
Adjust JVM class count by explicit value or percentage. |
Note
Changing these variables does not disable automatic memory fitting.
Out of memory warning
If you decide to configure the memory settings yourself, you run the risk of encountering an out-of-memory warning.
Here are some possible reasons of why your container could run out of memory:
Heap memory is greater than the total available memory.
Nonheap memory is greater than the total available memory.
Heap + nonheap memory is greater than the total available memory.
If your container runs out of memory, then you encounter the following warning:
OOM Warning: heap memory 1200M is greater than 1G available for allocation (-Xmx1200M)