Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8356194

[Linux] Increase default MaxRAMPercentage for containerized workloads

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Withdrawn
    • Icon: P3 P3
    • tbd
    • hotspot
    • None
    • behavioral
    • medium
    • Hide
      The default heap size if not otherwise configured with `MaxHeapSize` (or `-Xmx`) flags increases in a containerized deployment with a memory limit set on the container level. This might be unexpected for some systems that are expecting the old default of 25% of physical memory for heap. Such systems would need to explicitly set `MaxRAMPercentage` to the old value.
      Show
      The default heap size if not otherwise configured with `MaxHeapSize` (or `-Xmx`) flags increases in a containerized deployment with a memory limit set on the container level. This might be unexpected for some systems that are expecting the old default of 25% of physical memory for heap. Such systems would need to explicitly set `MaxRAMPercentage` to the old value.
    • Other
    • Implementation

      Summary

      Increase the default MaxRAMPercentage value on Linux for containerized systems which employ a container memory limit from 25% to 75%. This allows for better memory utilization when deployed on container orchestration systems such as Kubernetes with container memory limits already in place.

      Problem

      Deployments of the JVM in containers are common today. Many of those systems run on Kubernetes (K8S) and tune the memory needs on a per-pod or per-container basis. In such a scenario, the automatic container memory limit detection mechanism of the JVM kicks in. It derives the heap size from the detected physical memory. In case of a K8S pod which has a memory limit set, this would be the set memory limit. Most containerized deployments run a single application in that container/pod and expect the container to utilize the memory slice within its bounds as much as possible. The JVM default setting of 25% for MaxRAMPercentage prevents this from happening. Only 1/4 of the container memory limit could be used for the Java heap before OutOfMemoryErrors would be thrown.

      The default JVM setting of MaxRAMPercentage of 25% makes sense for multi-user deployments. After all, other users might run other JVM processes on the same system that would compete for memory.

      This is different In modern cloud environments. Applications are tuned at the container level in terms of resource allocation and expect applications to run well in such resource-constrained environments. Allowing the JVM to only use 25% of the container memory limit for its heap runs contrary to this goal as there is likely no other JVM to compete for heap/off-heap memory within that container. Most of the memory should be available for the heap and only a smaller portion for off-heap memory.

      Solution

      Increase the MaxRAMPercentage value for containerized systems that also employ a container memory limit from 25% to 75% to increase the chance of better memory utilization. Do this only when OSContainer::has_memory_limit() reports true, indicating a containerized Linux system with a set container memory limit.

      Specification

      diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
      index 9bd45b0fec8..aa6e28b0ac1 100644
      --- a/src/hotspot/os/linux/os_linux.cpp
      +++ b/src/hotspot/os/linux/os_linux.cpp
      @@ -4432,6 +4432,13 @@ void os::pd_init_container_support() {
         OSContainer::init();
       }
      
      +// Called before ergonomic flags processing
      +void os::initialize_max_ram_percentage() {
      +  if (OSContainer::has_memory_limit()) {
      +    FLAG_SET_ERGO_IF_DEFAULT(MaxRAMPercentage, 75.0);
      +  }
      +}
      +
       void os::Linux::numa_init() {
      
         // Java can be invoked as
      diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp
      index ee1f0a3b081..58f1e740f97 100644
      --- a/src/hotspot/share/runtime/os.cpp
      +++ b/src/hotspot/share/runtime/os.cpp
      @@ -484,6 +484,7 @@ void os::init_before_ergo() {
         // VM version initialization identifies some characteristics of the
         // platform that are used during ergonomic decisions.
         VM_Version::init_before_ergo();
      +  LINUX_ONLY(initialize_max_ram_percentage();)
       }
      
       void os::initialize_jdk_signal_support(TRAPS) {
      diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
      index dde80806912..e6f5ec77cfd 100644
      --- a/src/hotspot/share/runtime/os.hpp
      +++ b/src/hotspot/share/runtime/os.hpp
      @@ -256,6 +256,7 @@ class os: AllStatic {
         static void initialize_initial_active_processor_count();
      
         LINUX_ONLY(static void pd_init_container_support();)
      +  LINUX_ONLY(static void initialize_max_ram_percentage();)
      
         static void init(void);                      // Called before command line parsing

      Compatibility Risks

      General Linux deployments outside containers:

      There is expected to be no difference in behaviour after this CSR.

      Kubernetes:

      Kubernetes has configuration options for "Memory requests" and "Memory limit". If "Memory limit" is not set, Kubernetes runs the container with no (upper) memory limit. After this CSR, the JVM will use 25% of the container host memory for its heap size as before. If "Memory limit" is set on the Kubernetes deployment level, then each JVM will use 75% of the set container limit for its heap size within that container. The expectation is for there to be only one JVM. However, this could be problematic for containers which spawn many JVMs, like maven builds. In that case it is recommended to explicitly set -XX:MaxRAMPercentage to the old value.

      Other Linux-based container orchestration environments

      In general, for Linux containers with a memory limit set, any JVM process will be able to use more memory for the Java heap than it used to previously within that container. If that is not desired, then setting -XX:MaxRAMPercentage=25.0 will revert to the old behavour.

            sgehwolf Severin Gehwolf
            sgehwolf Severin Gehwolf
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: