OpenJDK G1 Patch

Rodrigo Bruno rbruno at
Sat May 19 18:01:19 UTC 2018

Dear OpenJDK community,

Jelastic <> and INESC-ID <> have
developed a patch for OpenJDK that improves elasticity of JVM with variable
loads. The detailed description of the patch can be found below. We would
like share this patch with the community and push it to the mainstream. We
believe this work will help Java community to make JVM even better and
improve the memory resources usage (save money) in the modern cloud
environments. A more complete patch description can be found in the paper
<> that
will be presented in ISMM 2018.

Elastic JVM Patch Description

Elasticity is the key feature of the cloud computing. It enables to scale
resources according to application workloads timely. Now we live in the
container era. Containers can be scaled vertically on the fly without
downtime. This provides much better elasticity and density compared to VMs.
However, JVM-based applications are not fully container-ready. The first
issue is that HotSpot JVM doesn’t release unused committed Heap memory
automatically, and, therefore, JVM can’t scale down without an explicit
call of the full GC. Secondly, it is not possible to increase the size of
JVM Heap in runtime. If your production application has an unpredictable
traffic spike, the only one way to increase the Heap size is to restart the
JVM with a new Xmx parameter.

To solve these 2 major issues and make JVM more container friendly, we have
implemented the following improvements: i) timely reduce the amount of
unused committed memory; and ii) dynamically limit how large the used and
committed memory can grow. The patch is implemented for the Garbage First

Timely Reducing Unused Committed Memory

To accomplish this goal, the HotSpot JVM was modified to periodically
trigger a full collection. Two full collections should not be separated by
more than GCFrequency seconds, a dynamically user-defined variable. The
GCFrequency value is ignored and therefore, i.e., no full collection is
triggered, if:


   GCFrequency is zero or below;

   the average load on the host system is above MaxLoadGC. The MaxLoadGC is
   a dynamically user-defined variable. This check is ignored if MaxLoadGC
   is zero or below;

   the committed memory  is above MinCommitted bytes. MinCommitted is a
   dynamically user-defined variable. This check is ignored if MinCommitted
   is zero or below;

   the difference between the current heap capacity and the current heap
   usage is below MaxOverCommitted bytes. The MaxOverCommitted is a
   dynamically user-defined variable. This check is ignored if
   MaxOverCommitted is zero or below;

The previously mentioned concepts are illustrated in the figure below:

The figure above depicts an application execution example where all the
aforementioned variables come into play. The default value for all
introduced variables (GCFrequency, MaxLoadGC, MaxOverCommitted, and,
MinCommitted) is zero. In other words, by default, there are no periodic

With this these modifications, it is possible to periodically eliminate
unused committed memory in HotSpot. This is very important for applications
that do not trigger collections very frequently and that might hold high
amounts of unused committed memory. One example are web servers, whose
caches can timeout after some minutes and whose memory might be
underutilized (after the caches timeout) at night when the amount of
requests is very low.

-Xmx Dynamic Limit Update

To dynamically limit how large the committed memory (i.e. the heap size)
can grow, a new dynamically user-defined variable was introduced:
CurrentMaxHeapSize. This variable (defined in bytes) limits how large the
heap can be expanded. It can be set at launch time and changed at runtime.
Regardless of when it is defined, it must always have a value equal or
below to MaxHeapSize (Xmx - the launch time option that limits how large
the heap can grow). Unlike MaxHeapSize, CurrentMaxHeapSize, can be
dynamically changed at runtime.

For example dynamically set 1GB as the new Xmx limit

jinfo -flag CurrentMaxHeapSize=1g <java_pid>

Setting CurrentMaxHeapSize at runtime will trigger a full collection if the
desired value is below the current heap size. After finishing the full
collection, a second test is done to verify if the desired value is still
above the heap size (note that a full collection will try to shrink the
heap as much as possible). If the value is still below the current heap
size, then an error is reported to the user. Otherwise, the operation is

The limit imposed by the CurrentMaxHeapSize can be disabled if the variable
is unset at launch time or if it is set to zero or below at runtime.

This feature is important to cope with changes in workload demands and to
avoid having to restart JVMs to cope with workload changes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the hotspot-gc-dev mailing list