# IBM J9 VM 8

This page describes the Optimization Pack for Eclipse OpenJ9 (formerly known as IBM J9) Virtual Machine version 8.

## Metrics

### All metrics

<table><thead><tr><th width="285">Name</th><th width="103.33333333333331">Unit</th><th>Description</th></tr></thead><tbody><tr><td>jvm_heap_size</td><td>bytes</td><td>The size of the JVM heap memory</td></tr><tr><td>jvm_heap_used</td><td>bytes</td><td>The amount of heap memory used</td></tr><tr><td>jvm_heap_util</td><td>percent</td><td>The utilization % of heap memory</td></tr><tr><td>jvm_memory_used</td><td>bytes</td><td>The total amount of memory used across all the JVM memory pools</td></tr><tr><td>jvm_memory_used_details</td><td>bytes</td><td>The total amount of memory used broken down by pool (e.g., code-cache, compressed-class-space)</td></tr><tr><td>jvm_memory_buffer_pool_used</td><td>bytes</td><td>The total amount of bytes used by buffers within the JVM buffer memory pool</td></tr><tr><td>jvm_gc_time</td><td>percent</td><td>The % of wall clock time the JVM spent doing stop the world garbage collection activities</td></tr><tr><td>jvm_gc_time_details</td><td>percent</td><td>The % of wall clock time the JVM spent doing stop the world garbage collection activities broken down by type of garbage collection algorithm (e.g., ParNew)</td></tr><tr><td>jvm_gc_count</td><td>collections/s</td><td>The total number of stop the world JVM garbage collections that have occurred per second</td></tr><tr><td>jvm_gc_count_details</td><td>collections/s</td><td>The total number of stop the world JVM garbage collections that have occurred per second, broken down by type of garbage collection algorithm (e.g., G1, CMS)</td></tr><tr><td>jvm_gc_duration</td><td>seconds</td><td>The average duration of a stop the world JVM garbage collection</td></tr><tr><td>jvm_gc_duration_details</td><td>seconds</td><td>The average duration of a stop the world JVM garbage collection broken down by type of garbage collection algorithm (e.g., G1, CMS)</td></tr><tr><td>jvm_threads_current</td><td>threads</td><td>The total number of active threads within the JVM</td></tr><tr><td>jvm_threads_deadlocked</td><td>threads</td><td>The total number of deadlocked threads within the JVM</td></tr><tr><td>jvm_compilation_time</td><td>milliseconds</td><td>The total time spent by the JVM JIT compiler compiling bytecode</td></tr></tbody></table>

## Parameters

### Heap

<table><thead><tr><th>Name</th><th>Type</th><th width="122">Unit</th><th>Default</th><th>Domain</th><th>Restart</th><th>Description</th></tr></thead><tbody><tr><td>j9vm_minHeapSize</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>Minimum heap size (in megabytes)</td></tr><tr><td>j9vm_maxHeapSize</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>Maximum heap size (in megabytes)</td></tr><tr><td>j9vm_minFreeHeap</td><td>real</td><td>percent</td><td><code>0.3</code></td><td><code>0.1</code> → <code>0.5</code></td><td>yes</td><td>Specify the minimum % free heap required after global GC</td></tr><tr><td>j9vm_maxFreeHeap</td><td>real</td><td>percent</td><td><code>0.6</code></td><td><code>0.4</code> → <code>0.9</code></td><td>yes</td><td>Specify the maximum % free heap required after global GC</td></tr></tbody></table>

### Garbage Collection

<table><thead><tr><th width="202">Name</th><th width="127">Type</th><th width="96">Unit</th><th>Default</th><th width="157">Domain</th><th width="101">Restart</th><th width="198">Description</th></tr></thead><tbody><tr><td>j9vm_gcPolicy</td><td>categorical</td><td> </td><td><code>gencon</code></td><td><code>gencon</code>, <code>subpool</code>, <code>optavgpause</code>, <code>optthruput</code>, <code>nogc</code></td><td>yes</td><td>GC policy to use</td></tr><tr><td>j9vm_gcThreads</td><td>integer</td><td>threads</td><td>You should select your own default value.</td><td><code>1</code> → <code>64</code></td><td>yes</td><td>Number of threads the garbage collector uses for parallel operations</td></tr><tr><td>j9vm_scvTenureAge</td><td>integer</td><td> </td><td><code>10</code></td><td><code>1</code> → <code>14</code></td><td>yes</td><td>Set the initial tenuring threshold for generational concurrent GC policy</td></tr><tr><td>j9vm_scvAdaptiveTenureAge</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xgc:scvNoAdaptiveTenure</code></td><td>yes</td><td>Enable the adaptive tenure age for generational concurrent GC policy</td></tr><tr><td>j9vm_newSpaceFixed</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>The fixed size of the new area when using the gencon GC policy. Must not be set alongside min or max</td></tr><tr><td>j9vm_minNewSpace</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>The initial size of the new area when using the gencon GC policy</td></tr><tr><td>j9vm_maxNewSpace</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>The maximum size of the new area when using the gencon GC policy</td></tr><tr><td>j9vm_oldSpaceFixed</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>The fixed size of the old area when using the gencon GC policy. Must not be set alongside min or max</td></tr><tr><td>j9vm_minOldSpace</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>The initial size of the old area when using the gencon GC policy</td></tr><tr><td>j9vm_maxOldSpace</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>The maximum size of the old area when using the gencon GC policy</td></tr><tr><td>j9vm_concurrentScavenge</td><td>categorical</td><td> </td><td><code>concurrentScavenge</code></td><td><code>concurrentScavenge</code>, <code>noConcurrentScavenge</code></td><td>yes</td><td>Support pause-less garbage collection mode with gencon</td></tr><tr><td>j9vm_gcPartialCompact</td><td>categorical</td><td> </td><td><code>nopartialcompactgc</code></td><td><code>nopartialcompactgc</code>, <code>partialcompactgc</code></td><td>yes</td><td>Enable partial compaction</td></tr><tr><td>j9vm_concurrentMeter</td><td>categorical</td><td> </td><td><code>soa</code></td><td><code>soa</code>, <code>loa</code>, <code>dynamic</code></td><td>yes</td><td>Determine which area is monitored by the concurrent mark</td></tr><tr><td>j9vm_concurrentBackground</td><td>integer</td><td> </td><td><code>0</code></td><td><code>0</code> → <code>128</code></td><td>yes</td><td>The number of background threads assisting the mutator threads in concurrent mark</td></tr><tr><td>j9vm_concurrentSlack</td><td>integer</td><td>megabytes</td><td><code>0</code></td><td>You should select your own domain.</td><td>yes</td><td>The target size of free heap space for concurrent collectors</td></tr><tr><td>j9vm_concurrentLevel</td><td>integer</td><td>percent</td><td><code>8</code></td><td><code>0</code> → <code>100</code></td><td>yes</td><td>The ratio between the amount of heap allocated and the amount of heap marked</td></tr><tr><td>j9vm_gcCompact</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xcompactgc</code>, <code>-Xnocompactgc</code></td><td>yes</td><td>Enables full compaction on all garbage collections (system and global)</td></tr><tr><td>j9vm_minGcTime</td><td>real</td><td>percent</td><td><code>0.05</code></td><td><code>0.0</code> → <code>1.0</code></td><td>yes</td><td>The minimum percentage of time to be spent in garbage collection, triggering the resize of the heap to meet the specified values</td></tr><tr><td>j9vm_maxGcTime</td><td>real</td><td>percent</td><td><code>0.13</code></td><td><code>0.0</code> → <code>1.0</code></td><td>yes</td><td>The maximum percentage of time to be spent in garbage collection, triggering the resize of the heap to meet the specified values</td></tr><tr><td>j9vm_loa</td><td>categorical</td><td> </td><td><code>loa</code></td><td><code>loa</code>, <code>noloa</code></td><td>yes</td><td>Enable the allocation of the large area object during garbage collection</td></tr><tr><td>j9vm_loa_initial</td><td>real</td><td> </td><td><code>0.05</code></td><td><code>0.0</code> → <code>0.95</code></td><td>yes</td><td>The initial portion of the tenure area allocated to the large area object</td></tr><tr><td>j9vm_loa_minimum</td><td>real</td><td> </td><td><code>0.01</code></td><td><code>0.0</code> → <code>0.95</code></td><td>yes</td><td>The minimum portion of the tenure area allocated to the large area object</td></tr><tr><td>j9vm_loa_maximum</td><td>real</td><td> </td><td><code>0.5</code></td><td><code>0.0</code> → <code>0.95</code></td><td>yes</td><td>The maximum portion of the tenure area allocated to the large area object</td></tr></tbody></table>

### JIT

<table><thead><tr><th width="156">Name</th><th>Type</th><th>Unit</th><th>Default</th><th>Domain</th><th width="91">Restart</th><th width="143">Description</th></tr></thead><tbody><tr><td>j9vm_jitOptlevel</td><td>ordinal</td><td> </td><td><code>noOpt</code></td><td><code>noOpt</code>, <code>cold</code>, <code>warm</code>, <code>hot</code>, <code>veryHot</code>, <code>scorching</code></td><td>yes</td><td>Force the JIT compiler to compile all methods at a specific optimization level</td></tr><tr><td>j9vm_compilationThreads</td><td>integer</td><td>integer</td><td>You should select your own default value.</td><td><code>1</code> → <code>7</code></td><td>yes</td><td>Number of JIT threads</td></tr><tr><td>j9vm_codeCacheTotal</td><td>integer</td><td>megabytes</td><td>You should select your own default value.</td><td>You should select your own domain.</td><td>yes</td><td>Maximum size limit in MB for the JIT code cache</td></tr><tr><td>j9vm_jit_count</td><td>integer</td><td> </td><td><code>10000</code></td><td><code>0</code> → <code>1000000</code></td><td>yes</td><td>The number of times a method is called before it is compiled</td></tr></tbody></table>

### Other parameters

<table><thead><tr><th width="164">Name</th><th width="118">Type</th><th width="71">Unit</th><th>Default</th><th>Domain</th><th width="94">Restart</th><th width="136">Description</th></tr></thead><tbody><tr><td>j9vm_lockReservation</td><td>categorical</td><td></td><td>categorical</td><td><em>blank</em>, <code>-XlockReservation</code></td><td>no</td><td>Enables an optimization that presumes a monitor is owned by the thread that last acquired it</td></tr><tr><td>j9vm_compressedReferences</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xcompressedrefs</code>, <code>-Xnocompressedrefs</code></td><td>yes</td><td>Enable/disable the use of compressed references</td></tr><tr><td>j9vm_aggressiveOpts</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xaggressive</code></td><td>yes</td><td>Enable the use of aggressive performance optimization features, which are expected to become default in upcoming releases</td></tr><tr><td>j9vm_virtualized</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xtune:virtualized</code></td><td>yes</td><td>Optimize the VM for virtualized environment, reducing CPU usage when idle</td></tr><tr><td>j9vm_shareclasses</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xshareclasses</code></td><td>yes</td><td>Enable class sharing</td></tr><tr><td>j9vm_quickstart</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xquickstart</code></td><td>yes</td><td>Run JIT with only a subset of optimizations, improving the performance of short-running applications</td></tr><tr><td>j9vm_minimizeUserCpu</td><td>categorical</td><td> </td><td><em>blank</em></td><td><em>blank</em>, <code>-Xthr:minimizeUserCPU</code></td><td>yes</td><td>Minimizes user-mode CPU usage in thread synchronization where possible</td></tr></tbody></table>

## Domains

The following parameters require their ranges or default values to be updated according to the described rules:&#x20;

### Memory

<table><thead><tr><th>Parameter</th><th width="279.3333333333333">Default value</th><th>Domain</th></tr></thead><tbody><tr><td>j9vm_minNewSpace</td><td>25% of <code>j9vm_minHeapSize</code></td><td>must not exceed <code>j9vm_minHeapSize</code></td></tr><tr><td>j9vm_maxNewSpace</td><td>25% of j9vm_maxHeapSize</td><td>must not exceed <code>j9vm_maxHeapSize</code></td></tr><tr><td>j9vm_minOldSpace</td><td>75% of j9vm_minHeapSize</td><td>must not exceed <code>j9vm_minHeapSize</code></td></tr><tr><td>j9vm_maxOldSpace</td><td>same as j9vm_maxHeapSize</td><td>must not exceed <code>j9vm_maxHeapSize</code></td></tr><tr><td>j9vm_gcthreads</td><td>number of CPUs - 1, up to a maximum of 64</td><td>capped to default, no benefit in exceeding that value</td></tr><tr><td>j9vm_compressedReferences</td><td>enabled for j9vm_maxHeapSize&#x3C;= 57 GB</td><td> </td></tr></tbody></table>

Notice that the value `nocompressedreferences` for `j9vm_compressedReferences` can only be specified for JVMs compiled with the proper `--with-noncompressedrefs` flag. If this is not the case you cannot actively disable compressed references, meaning:

* for Xmx <= 57GB is useless to tune this parameter since compressed references are active by default and it is not possible to explicitly disable it
* for Xmx > 57GB, since the by default (blank value) compressed references are disabled, Akamas can try to enable it. This requires removing the `nocompressedreferences` from the domain

## Constraints

The following tables show a list of constraints that may be required in the definition of the study, depending on the tuned parameters:

### Memory

<table><thead><tr><th width="495">Formula</th><th>Notes</th></tr></thead><tbody><tr><td>jvm.j9vm_minHeapSize &#x3C; jvm.j9vm_maxHeapSize</td><td> </td></tr><tr><td>jvm.j9vm_minNewSpace &#x3C; jvm.j9vm_maxNewSpace &#x26;&#x26;<br>jvm.j9vm_minNewSpace &#x3C; jvm.j9vm_minHeapSize &#x26;&#x26;<br>jvm.j9vm_maxNewSpace &#x3C; jvm.j9vm_maxHeapSize</td><td> </td></tr><tr><td>jvm.j9vm_minOldSpace &#x3C; jvm.j9vm_maxOldSpace &#x26;&#x26;<br>jvm.j9vm_minOldSpace &#x3C; jvm.j9vm_minHeapSize &#x26;&#x26;<br>jvm.j9vm_maxOldSpace &#x3C; jvm.j9vm_maxHeapSize</td><td> </td></tr><tr><td>jvm.j9vm_loa_minimum &#x3C;= jvm.j9vm_loa_initial &#x26;&#x26;<br>jvm.j9vm_loa_initial &#x3C;= jvm.j9vm_loa_maximum</td><td> </td></tr><tr><td>jvm.j9vm_minFreeHeap + 0.05 &#x3C; jvm.j9vm_maxFreeHeap</td><td> </td></tr><tr><td>jvm.j9vm_minGcTimeMin &#x3C; jvm.j9vm_maxGcTime</td><td> </td></tr></tbody></table>

Notice that

* `j9vm_newSpaceFixed` is mutually exclusive with `j9vm_minNewSpace` and `j9vm_maxNewSpace`
* `j9vm_oldSpaceFixed` is mutually exclusive with `j9vm_minOldSpace` and `j9vm_maxOldSpace`
* the sum of `j9vm_minNewSpace` and `j9vm_minOldSpace` must be equal to `j9vm_minHeapSize`, so it's useless to tune all of them together. Max values seem to be more complex.
