JDK-8186315 : Allow more flexibility in selecting Heap % of available RAM
  • Type: CSR
  • Component: hotspot
  • Sub-Component: gc
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 10
  • Submitted: 2017-08-16
  • Updated: 2017-08-31
  • Resolved: 2017-08-31
Related Reports
CSR :  

To better control heap memory allocations, three existing flags based on fractions, 1/N for a provided value of N, are deprecated (-XX:MaxRAMFraction=xxx,  -XX:MinRAMFaction=xxx and -XX:InitialRAMFraction=xxx) and three new flags based on percentages, from 0.0 to 100.0, are being introduced (-XX:MaxRAMPercentage -XX:MinRAMPercentage and -XX:InitialRAMPercentage).


Using the -XX:MaxRAMFraction options, we can only set fractional values 1/2, 1/3, 1/4 etc.   Customers would like the ability to select larger amounts beyond 1/2 of available RAM.  This can be accomplished by setting hard coded amounts using -Xmx but the requesting customer would like this value to be based on the amount of available memory.   In the case where 60% of available host RAM is desired the user would like a flag which would allow them to specify 60.


Deprecate three existing Hotspot flags  -XX:MaxRAMFraction=xxx,  -XX:MinRAMFaction=xxx and -XX:InitialRAMFraction=xxx) and add three new flags (-XX:MaxRAMPercentage -XX:MinRAMPercentage and -XX:InitialRAMPercentage) which allow floating point values to be used to specify the percentage of available host memory to be used for Max, Min and Initial Heap sizes.


Here is my proposed patch for the flag name changes:

       product(uintx, MaxRAMFraction, 4,                                         
               "Maximum fraction (1/n) of real memory used for maximum heap "    
    -          "size")                                                           
    +          "size. "                                                          
    +          "Deprecated, use MaxRAMPercentage instead")                       
               range(1, max_uintx)                                               
       product(uintx, MinRAMFraction, 2,                                         
               "Minimum fraction (1/n) of real memory used for maximum heap "    
    +          "size on systems with small physical memory size. "               
    +          "Deprecated, use MinRAMPercentage instead")                       
    +          range(1, max_uintx)                                               
    +  product(uintx, InitialRAMFraction, 64,                                    
    +          "Fraction (1/n) of real memory used for initial heap size. "      
    +          "Deprecated, use InitialRAMPercentage instead")                   
    +          range(1, max_uintx)                                               
    +  product(double, MaxRAMPercentage, 25.0,                                   
    +          "Maximum percentage of real memory used for maximum heap size")   
    +          range(0.0, 100.0)                                                 
    +  product(double, MinRAMPercentage, 50.0,                                   
    +          "Minimum percentage of real memory used for maximum heap"         
               "size on systems with small physical memory size")                
    -          range(1, max_uintx)                                               
    -  product(uintx, InitialRAMFraction, 64,                                    
    -          "Fraction (1/n) of real memory used for initial heap size")       
    -          range(1, max_uintx)                                               
    +          range(0.0, 100.0)                                                 
    +  product(double, InitialRAMPercentage, 1.5625,                             
    +          "Percentage of real memory used for initial heap size")           
    +          range(0.0, 100.0)

The new flags, if specified, will override the deprecated older flags.

Moving to approved.

Yes, I intend on deprecating the flags. I did not include the entire changset in the CSR request. I only added globals.hpp to show the new and old flag changes with their default values. This is what a user will see if they use any of these deprecated flags. ./java -XX:MaxRAMFraction=1 Java HotSpot(TM) 64-Bit Server VM warning: Option MaxRAMFraction was deprecated in version 10.0 and will likely be removed in a future release.

[~bobv] I do not understand, do you intend to deprecate the flags -XX:MaxRAMFraction and -XX:MinRAMFraction in JDK 10 or not? The "description" for each flag in globals.hpp is not part of any product build, so an end user will never see your comment "Deprecated, use MaxRAMPercentage instead".

I was originally going to deprecate the current flags in a future release but the CSR feedback plus comments from others suggested that I do it in JDK 10. These flags will continue to work in JDK 10 and I have not yet marked them for obsolescence.

Thanks Erik. A simple google search does show MaxRAMFraction gets mentioned a lot in blogs and posts.

Yes, I know. Again, I just wanted to provide some additional insight that at least MaxRAMFraction is a used flag (I would almost say widely used). I'm not part of the CSR and I do not have a problem with the decision that the CSR reaches, I just wanted you all to be aware of the circumstances. That is all :)

> "both flags to co-exist for at least one release (perhaps along with deprecation)" That's exactly what you will get with deprecation.

Heh, I'm all for deprecating (and removing) flags :) I only wanted to point out that this flag (-XX:MaxRAMFraction) happens to be a rather widely used flag. At least in the GC team, we usually try to weigh how common a flag is whenever we deprecate one. If we think the flag is common, then we usually try to provide a way for both flags to co-exist for at least one release (perhaps along with deprecation) and then remove/deprecate in a later release. I don't mind the consensus algorithm that -XX:MaxRAMPercentage always trumps -XX:MaxRAMFraction.

I think we don't want to keep expanding the number of flags supported and deprecation is the process we have for managing that when a "better" flag comes along. That said, aliasing would be a possibility here - if we had a better mechanism in place to support it. The current mechanism is simply textual replacement: Foo=x becomes Bar=x. To actually convert from fractions to % requires a new mechanism (or a one-off special chunk of code just for these flags - which I would not like to see). There is also a problem with "last flag wins" in this case as these flags are only applied when we set up the heap size - at which point we have no idea what order the flags were seen. Hence the current approach to have a % override a fraction.

I just wanted to chime in with a comment from a GC developer :) As far as we know (this is always hard to measure), the flag MaxRAMFraction is widely used. Just internally we use MaxRAMFraction for every nightly test being run. Even though the -XX:* does not come with any backwards compability, deprecation is still inconvenient for our users, particularly if it is a very common flag. It seems fairly simple to promote -XX:MaxRAMPercentage as the new, recommended way and keep -XX:MaxRAMFraction around as an alias? -XX:MaxRAMFraction=8 can easily be translated into Just -XX:MaxRAMPercentage=1/8. This of course means we have to handle situation of: -XX:MaxRAMFraction=4 -XX:MaxRAMPercentage=50, but the usual hotspot way seems fine here: print a warning and last flag on the command line "wins". What do you think?

Please update the Summary section to be a condensed version of what is being changed ("To better control heap memory allocations, three existing flags based on fractions, 1/N for a provided value of N, are deprecated and three new flags based on percentages, from 0.0 to 100.0, are introduced...") rather than a short statement of the problem.

I agree that a new flag provides a better UI. I will change my proposal to added these new flags and will mark the existing flags as deprecated. -XX:MaxRAMPercentage -XX:MinRAMPercentage -XX:InitialRAMPercentage With values ranging from 0 to 100.

Procedurally, I'm advancing this CSR to accepted for the concept of adding/changing a flag for this purpose. Before the request is finalized for the second phase of CSR review, please get one or more reviewers of the request and get a consensus on the UI to offer here.

I think the percentage version of the flag offers a better UI than having to specify the reciprocal of the value one wants. Presumably there can be precedence rules if two flags are specified or use of both flags could be rejected. If a second flag is added for this feature, I assume the old one will be marked obsolete, etc.

I think for consistency if we change Max and Min then we should also change InitialRAMFraction. RAM is an acronym so it should remain all-caps (even though that doesn't work well with CamelCase). I'd hate to see yet-another-flag for MaxRAMPercentage but from a technical perspwective handling it would not be problematic - the existing flags can easily be converted to percentages and the general rule is "last option wins".. But I also have no problem with 1/N where N can be a fraction - though as pointed out in the code-review we must have N >= 1

I don't disagree that your usage would be better but I was trying to avoid adding a new option. Since this flag has been documented as: "Maximum fraction (1/n) of real memory used for maximum heap" I did not want to break compatibility. If you feel my overloading of the existing flag is unacceptable, I can use my suggested new flag: -XX:MaxRAMPercentage=25 (for 25% of total memory) The downside of adding a new flag is deciding which one takes precedence when both flags are provided. As for the RAM versus Ram, there are a few other flags that use RAM, MaxRAM for example, so we don't want to add inconsistent uses of this acronym.

For an option named something like MaxRAMFraction, I would expect if it was a floating-point value, it was a fraction it would be interpreted directly rather than as a reciprocal. In other words, to use one quarter of memory, say MaxRAMFraction=0.25 rather than MaxRAMFraction=4.0. Also "MaxRamFraction" is easier to read than "MaxRAMFraction".