JDK-8371987 : Remove default value of InitialRAMPercentage
  • Type: CSR
  • Component: hotspot
  • Sub-Component: gc
  • Priority: P4
  • Status: Draft
  • Resolution: Unresolved
  • Fix Versions: 26
  • Submitted: 2025-11-17
  • Updated: 2025-11-17
Related Reports
CSR :  
Description
Summary
-------

This change proposes to eliminate the default value of `InitialRAMPercentage`, which influences how `InitialHeapSize` is determined. Instead, `InitialHeapSize` will always default to the value of `MinHeapSize`, the lowest permissible heap initialization value, unless overridden by user configuration.

Problem
-------
Historically, the default value for `InitialRAMPercentage` was 1/64 of the available system memory, capped at 1/64 of 128GB. With [JDK-8348278](https://bugs.openjdk.org/browse/JDK-8348278), this percentage was reduced to 1/512 to boost startup performance by shrinking initial heap allocation. As a result, the `InitialRAMPercentage` calculation became capped at 1/512 of 128GB instead. Previous changes in [JDK-8369346](https://bugs.openjdk.org/browse/JDK-8369346) removed the default value for and deprecated the `MaxRAM` flag to simplify reasoning about ergonomic heap size selection. As a result, the previous cap of 1/512 of 128GB no longer applies, and the calculation is now based solely on the actual system memory size. However, the fixed-percentage approach of `InitialRAMPercentage` leads to non-intuitive and error-prone behavior:

- **Inconsistency Across Environments:** The current approach causes `InitialHeapSize` to vary dramatically based on total system memory rather than user-specified limits, leading to initial heap sizes as large as 4GB on a 2TB machine but only 128MB on a 64GB machine, regardless of `-Xmx` setting. This results in unpredictable and sometimes suboptimal behavior that doesn't consistently align with user intent.
- **Interaction With Other Flags:** When either the default or a user-supplied value for `InitialRAMPercentage` causes `InitialHeapSize` to exceed `MaxHeapSize`, `InitialHeapSize` is automatically capped at `MaxHeapSize`. This behavior is subtle, as the ergonomics will effectively ignore the value for `InitialHeapSize` if it exceeds `MaxHeapSize`, always enforcing the maximum heap limit. This is especially confusing for users who configure such a value manually.
- **Complexity & Opacity:** The interaction of `InitialRAMPercentage`, `InitialHeapSize`, `MinHeapSize`, and `MaxHeapSize` creates a system that is hard for users to reason about, making memory tuning unnecessarily opaque and introducing potential for subtle bugs.

Solution
--------
Defaulting `InitialHeapSize` to `MinHeapSize` brings several advantages. Most importantly, it provides simplicity and predictability, ensuring users can easily understand the default behavior of the `InitialRAMPercentage` flag. This step aligns closely with existing JVM ergonomics, since specifying `-Xms` already sets both `MinHeapSize` and `InitialHeapSize`, making their connection explicit, intuitive, and consistent for users.

It is important to emphasize that selecting a default value for `InitialRAMPercentage` fundamentally involves a trade-off between startup and runtime performance. A larger initial heap size grants the GC more headroom initially, potentially reducing early GC cycles and resizing events. In contrast, a smaller initial heap can result in more GC activity and resizing as the heap fills up and adjusts to demand at runtime. However, it is extremely challenging to pick a single numeric default that suits the needs of most applications, given their diversity. Therefore, we propose to always choose the minimum possible initial heap size, as this consistently optimizes for startup performance. For users more concerned with runtime performance than startup, they are always able to explicitly configure the `InitialHeapSize` via one of `-Xms`, `-XX:InitialHeapSize`, or `-XX:InitialRAMPercentage` to meet their requirements.

By making this the default behavior, we effectively remove opaque GC heuristics and provide a consistent, predictable starting point that is easy to understand and reason about. If the user hasn't specified their preferences, we optimize for what can be objectively beneficial, faster startup, while allowing users to tune for other needs as appropriate.

From a performance perspective, minimizing the initial heap size leads to faster startup, as targeted by [JDK-8353837](https://bugs.openjdk.org/browse/JDK-8353837). Adaptive heap growth ensures that additional memory requirements can still be met efficiently as the application runs. We share the same concerns and observations highlighted in [JDK-8353837](https://bugs.openjdk.org/browse/JDK-8353837): depending on the heap sizing policy of the chosen garbage collector, reducing the initial heap may trigger more frequent resizings until a stable heap size is reached. However, this behavior is generally not an issue for small, out-of-the-box applications. For long-running or production workloads, the impact is expected to be minimal since most memory-conscious applications already set `-Xms` explicitly, which overrides the `InitialRAMPercentage` setting. This approach aligns with current usage patterns, making the default `InitialRAMPercentage` largely redundant and occasionally confusing. By directly tying the initial heap allocation to `MinHeapSize`, we prevent non-intuitive scaling based on host memory size, leading to more consistent and predictable behavior across a wide range of environments.

### Summary

Removing the default value for `InitialRAMPercentage` and defaulting `InitialHeapSize` to `MinHeapSize` makes the JVM's startup memory behavior simpler, more predictable, and startup-performance-friendly. It avoids legacy quirks and aligns with best practices, giving users clearer expectations and greater control over application memory usage. This change only affects the default behavior in the absence of explicit user setting of `InitialRAMPercentage`.


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

```
  product(double, InitialRAMPercentage, 0,                                  \
          "Percentage of real memory used for initial heap size")           \
          range(0.0, 100.0)                                                 \
```