JDK-8223957 : Improve the behavior of Max RAM settings and UseCompressedOops
  • Type: CSR
  • Component: hotspot
  • Sub-Component: gc
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2019-05-15
  • Updated: 2019-07-29
  • Resolved: 2019-05-29
Related Reports
CSR :  
Description
Summary
-------

Update and improve the relationship between the MaxRAM, corresponding Fractional and Percentage RAM options and the UseCompressedOops flag.

Problem
-------

A few bugs have been filed recently by users due to the confusing relationship between the Hotspot VM options that are provided to override the default ergonomic behavior that configures the Java Heap size.

    https://bugs.openjdk.java.net/browse/JDK-8222252
    https://bugs.openjdk.java.net/browse/JDK-8213175
    
    The flags impacted are:
    
    -XX:MaxRAMPercentage
    -XX:MaxRAMFraction
    -XX:MinRAMPercentage
    -XX:MinRAMFraction
    -XX:InitialRAMPercentage
    -XX:InitialRAMFraction
    
    -XX:MaxRAM
    
    -XX:+/-UseCompressedOops

There are two major problems with the current behavior.

1. A user that wishes to specify that the Java Heap size will be configured to be a percentage of the available OS memory cannot guarantee that this will be accomplished with the -XX:MaxRAMPercentage flag.  This is due to the fact that the percentage is based on the MaxRAM flag and not physical memory.  In a system with memory greater than MaxRAM, setting MaxRAMPercentage only allows the heap to be that percentage of MaxRAM.

2.  Assuming we solve problem 1, the selected heap size is further limited by the compress oops memory limit (approx 32GB) without any warning or error.


Solution
--------

The solution is to provide higher priority to user specified options than ergonomic settings.  If a user specifies any of the flag options below, then the percentage or fraction will be based on the hosts available memory and not MaxRAM.  The only case where MaxRAM will be used is if the user ALSO specifies the MaxRAM option.

    -XX:MaxRAMPercentage
    -XX:MaxRAMFraction
    -XX:MinRAMPercentage
    -XX:MinRAMFraction
    -XX:InitialRAMPercentage
    -XX:InitialRAMFraction

Also, If any of these flags including MaxRAM are specified on the command line,
the selected Java heap size will not be limited by the compressed oop limit.

These changes will be documented in the JDK13 release notes.  There is also an existing Jira issue (https://bugs.openjdk.java.net/browse/JDK-8186984) to add and impove the VM documentation related to these VM options.  

Specification
-------------

         void Arguments::set_heap_size() {
    -  julong phys_mem =
    -    FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
    -                            : (julong)MaxRAM;
    +  julong phys_mem;
    +
    +  // If the user specified one of these options, they
    +  // want specific memory sizing so do not limit memory
    +  // based on compressed oops addressability.
    +  // Also, memory limits will be calculated based on
    +  // available os physical memory, not our MaxRAM limit,
    +  // unless MaxRAM is also specified.
    +  bool override_coop_limit = (!FLAG_IS_DEFAULT(MaxRAMPercentage) ||
    +                           !FLAG_IS_DEFAULT(MaxRAMFraction) ||
    +                           !FLAG_IS_DEFAULT(MinRAMPercentage) ||
    +                           !FLAG_IS_DEFAULT(MinRAMFraction) ||
    +                           !FLAG_IS_DEFAULT(InitialRAMPercentage) ||
    +                           !FLAG_IS_DEFAULT(InitialRAMFraction) ||
    +                           !FLAG_IS_DEFAULT(MaxRAM));
    +  if (override_coop_limit) {
    +    if (FLAG_IS_DEFAULT(MaxRAM)) {
    +      phys_mem = os::physical_memory();
    +      FLAG_SET_ERGO(MaxRAM, (uint64_t)phys_mem);
    +    } else {
    +      phys_mem = (julong)MaxRAM;
    +    }
    +  } else {
    +    phys_mem = FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM)
    +                                       : (julong)MaxRAM;
    +  }
    +
     
       // Convert deprecated flags
       if (FLAG_IS_DEFAULT(MaxRAMPercentage) &&
    @@ -1780,7 +1804,19 @@
             // but it should be not less than default MaxHeapSize.
             max_coop_heap -= HeapBaseMinAddress;
           }
    -      reasonable_max = MIN2(reasonable_max, max_coop_heap);
    +
    +      // If user specified flags prioritizing os physical
    +      // memory limits, then disable compressed oops if
    +      // limits exceed max_coop_heap and UseCompressedOops
    +      // was not specified.
    +      if (reasonable_max > max_coop_heap) {
    +        if (FLAG_IS_ERGO(UseCompressedOops) && override_coop_limit) {
    +          FLAG_SET_ERGO(UseCompressedOops, false);
    +          FLAG_SET_ERGO(UseCompressedClassPointers, false);
    +        } else {
    +          reasonable_max = MIN2(reasonable_max, max_coop_heap);
    +        }
    +      }
         }
         reasonable_max = limit_by_allocatable_memory(reasonable_max);



Comments
Moving to Approved.
29-05-2019

Reviewed.
29-05-2019

I've updated JDK-8186984 and hopefully it will be targetted to this release. That said these flags are currently undocumented. I will review this once Bob has finalized the changes as per the RFR thread: [http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2019-May/025797.html][1] [1]: http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2019-May/025797.html
24-05-2019

It would be preferable for JDK-8186984 to be fixed in the same release as this bug fix. Moving back to Provisional; please have at least one other engineer review the CSR before it is Finalized. Thanks.
22-05-2019

Moving this request to Provisional. Before this request is Finalized, please include a discussion of how and where this change will be documented (release note, man page, etc.)
15-05-2019