RFR: JDK-8318016: Per-compilation memory ceiling

Thomas Stuefe stuefe at openjdk.org
Tue Oct 24 05:52:52 UTC 2023


This RFE introduces a new compile command to limit memory usage per compilation. It complements and is based upon the JIT memory statistic introduced with https://bugs.openjdk.org/browse/JDK-8317683.

This new memory limit is applied during compilation for either C1 or C2. It has one of two modes:
- *crash* mode (mainly for compiler devs), which aborts with hs-err file when the ceiling is reached, right in the compiler thread at the allocation point that triggered the ceiling
- *stop* mode, which stops the compilation similarly to how hitting the node limit in C2 would stop the compilation.

#### Usage

The compile command takes the form `-XX:CompileCommand:MemLimit,<method>,<memory size>[~<option>]`

The memory size that can be specified as usual. The command also takes an optional trailing option, separated from the memory size by a tilde (odd choice but needed because of https://bugs.openjdk.org/browse/JDK-8318214).

The `<suboption>` can be either `crash` or `stop` and distinguishes between the aforementioned modes. If omitted, the default is "stop".

Since `MemLimit` is based on the JIT statistic, it is implicitly enabled, so there is no need to explicitly enable it with `MemStat`.


Usage examples:


- crash when reaching 100m for a single compilation:
 

-XX:CompileCommand='MemLimit,*.*,100m~crash'


- limit all methods to a 2m footprint and print a trailing record at VM shutdown


-XX:CompileCommand='MemLimit,*.*,2m' -XX:CompileCommand='MemStat,*.*,print'


The JIT statistic table (printed either at VM shutdown or via `jcmd <pid> Compiler.memory`) now has a new column "result" that shows if the compilation was completed successfully or had an error or an oom:


                              vvvvv                                                                                                                                                                                                                                                
total     NA        RA        result  #nodes  time    type  #rc thread              method
3036016   687328    1757456   oom     2607    0,320   c2    1   0x00007fcf1c181550  java/lang/invoke/StringConcatFactory::<clinit>(()V)



#### Implementation notes

The crash variant works immediately.

The stop variant works delayed: If arena memory reaches the limit in the scope of a compilation, we signal the Compile object (`Compile` for c2, `Compilation` for c1) that an oom has occurred.

For C1, we set the bailout string right here. That causes the C1 compilation to fail at the next bailout check.

For C2, we cannot just set `Compile::_failure_reason` since I found that the C2 is not well prepared to bail out from wherever it is tested. So I incorporated the oom check in the nodelimit check C2 does. Note that even that needs some preparatory work (see https://github.com/openjdk/jdk/pull/16205, a prerequisite for this RFE).


Due to this delay, the actual memory used per compilation may be somewhat higher than the limit. In practice the limit works reasonably well, though.

-------------

Commit messages:
 - memlimit

Changes: https://git.openjdk.org/jdk/pull/16220/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=16220&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8318016
  Stats: 429 lines in 17 files changed: 395 ins; 3 del; 31 mod
  Patch: https://git.openjdk.org/jdk/pull/16220.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/16220/head:pull/16220

PR: https://git.openjdk.org/jdk/pull/16220


More information about the hotspot-compiler-dev mailing list