Enabling the DynamicMaxHeap Feature
Introduction
Internet customers widely deploy applications using containerization, where container resources support vertical scaling. However, the maximum heap size of OpenJDK can only be specified at application startup and cannot be dynamically scaled. As a result, Java applications are unable to utilize memory dynamically provisioned by the container runtime.
The DynamicMaxHeap feature introduces the concept of a modifiable maximum heap size. You can use the jcmd command to dynamically modify the target maximum Java heap size during application running without restarting the JVM.
Application Scenario
After container resources are expanded, the upper limit of the heap memory needs to be dynamically expanded so that applications can use extra container resources.
Restrictions
- The DynamicMaxHeap feature is supported in BiSheng JDK 8 since 8u452. The application must use the G1 garbage collector.
- The application must explicitly specify the maximum heap size after dynamic heap expansion (-XX:DynamicMaxHeapSizeLimit) and the initial maximum heap size (-XX:MaxHeapSize, that is, the value of -Xmx). In addition, the value of DynamicMaxHeapSizeLimit must be greater than MaxHeapSize to ensure that there is space for heap expansion.
- The application must not explicitly specify -XX:OldSize, -XX:NewSize, or -XX:MaxNewSize. Additionally, when this feature is used, -XX:UseAdaptiveGCBoundary must remain false (this is the default value if not explicitly set) and -XX:UseAdaptiveSizePolicy must remain true (this is the default value if not explicitly set).
- This feature cannot be used together with G1Uncommit. Therefore, -XX:+G1Uncommit cannot be added during application startup (defaults to false if not explicitly set).
- If this feature is enabled and -XX: DynamicMaxHeapSizeLimit>32GB is set at application startup, the JVM disables compressed oops.
How to Use
- Add the following JVM parameters at application startup to enable the DynamicMaxHeap feature:
- -XX:+TraceDynamicMaxHeap: bool type, indicating whether to enable the DynamicMaxHeap log tracing function. When enabled, this function logs the heap expansion process and causes of any execution failures into standard output. The output information will include the keyword "ChangeMaxHeapOp".
- -XX:DynamicMaxHeapSizeLimit=: uintx type, specifying the upper limit of heap expansion. The target maximum heap size specified using jcmd cannot exceed the value of this parameter. The default value is 96M (the same as the default value of -XX:MaxHeapSize). Setting this parameter enables the DynamicMaxHeap feature. This parameter must be used together with -XX:MaxHeapSize (that is, -Xmx) and must be greater than the value of -Xmx. In addition, this parameter can be used only with G1GC enabled. If the value is greater than 32 GB, compressed oops are disabled. If compressed oops are explicitly enabled, the "Max heap size too large for Compressed Oops" alarm is displayed and compressed oops are disabled. If this parameter is not added, the DynamicMaxHeap feature is disabled by default, and the original application is not affected.
- -XX:MaxHeapSize=: specifies the initial maximum heap size.
- -XX:+UseG1GC: enables G1GC.
The following is an example of using the startup parameters:
1 2 3 4 5
$JAVA_HOME/bin/java -XX:+TraceDynamicMaxHeap \ -XX:DynamicMaxHeapSizeLimit=4g \ -XX:MaxHeapSize=1g \ -XX:+UseG1GC \
The following is an example of using only necessary parameters for enabling the feature:
1$JAVA_HOME/bin/java -XX:DynamicMaxHeapSizeLimit=4g -XX:MaxHeapSize=1g -XX:+UseG1GC
- Run the following jcmd command to dynamically adjust the maximum heap size:
1$JAVA_HOME/bin/jcmd <PID> GC.change_max_heap <Target maximum heap size>
GC.change_max_heap adjusts the target value of the maximum heap size.
- How to use: jcmd <PID> GC.change_max_heap <Target maximum heap size>. The target value must be an integer, and the unit character can be k/K (KB), m/M (MB), or g/G (GB). If no unit character or other characters are entered, the default unit byte is used.
- Example:
1 2
jcmd <PID> GC.change_max_heap 2g //Valid. The target value is 2 GB. jcmd <PID> GC.change_max_heap 209715200 //Valid. The target value is 200 MB.
- If the maximum JVM heap memory is dynamically reduced to a value less than the current heap memory usage using jcmd, young GC or full GC may be triggered, causing application performance fluctuation.
If the adjustment is successful, "GC.change_max_heap success" is returned. If the adjustment fails, "failed" and the cause are returned.
If -XX:+TraceDynamicMaxHeap is enabled, detailed heap expansion logs are printed to the standard output of the application.