Java Garbage Collection Types and Settings in AccuWeb.Cloud
Performance and cost are crucial in application hosting. We often wonder how to reduce costs without hurting app performance. This article covers automatic memory management for Java apps on AccuWeb.Cloud using garbage collection.
Java Garbage Collection Overview
Garbage Collection (GC) is automatic memory management. It finds unused data in memory and frees up space for reuse.
When an object is created, it uses memory. This memory stays allocated as long as the object is in use. Once an object is no longer needed, its memory can be reclaimed, saving costs on unused resources.
We tested different Garbage Collectors (GC) and chose the best ones for Java apps on Accuweb.cloud, considering the platform’s automatic vertical scaling. We adjusted the default GC settings to enhance user benefits.
AccuWeb.Cloud supports these Garbage Collectors (GCs)
- G1 GC (-XX:+UseG1GC): This is the default GC in Accuweb.cloud PaaS. G1 is designed for servers with many processors and lots of memory. It divides memory into fixed-sized regions and collects garbage from regions with the least live data first.
- Shenandoah GC (-XX:+UseShenandoahGC): This GC works in parallel with the application to minimize pauses. It efficiently handles both small and large heaps without long pauses. It also uses the option -XX:ShenandoahGCHeuristics=compact.
- ZGC (-XX:+UseZGC): This low-latency GC is ideal for applications with large heaps. It does most of the garbage collection work in parallel with the application, minimizing the impact on response time. It uses the option -XX:ZCollectionInterval=$ZCOLLECTION_INTERVAL to set the maximum interval between GC cycles.
- Epsilon GC (-XX:+UseEpsilonGC): This passive GC only handles memory allocation and doesn’t reclaim memory. When the heap is full, the JVM stops. Epsilon GC is useful for debugging memory usage and measuring application performance.
- Parallel GCs
- ParNew GC (-XX:+UseParNewGC): A “stop-the-world” multithreaded GC that primarily collects young generation objects. Since the young generation is usually small, ParNew works quickly and doesn’t significantly impact your application. It also compacts unused RAM, supporting Accuweb.cloud’s automatic vertical scaling feature.
-
- Parallel GC (-XX:+UseParallelGC): This GC performs parallel collection on the young generation only. Unlike ParNew, it cannot be used simultaneously with ConcMarkSweep GC.
- Parallel Old GC (-XX:+UseParallelOldGC): Uses a parallel “mark and compact” algorithm. It stops all application threads, then uses multiple threads to mark and compact memory.
- ConcMarkSweep GC (-XX:+UseConcMarkSweepGC): Designed for applications needing shorter GC pauses and can share processor resources with the GC while running. It is suitable for applications that require low GC pause times.
- Serial GC (-XX:+UseSerialGC): Performs GC in a single thread with the lowest memory usage of all GCs, but causes long pauses that can degrade application performance.
Note: The Openj9 Java engine does not support the GCs listed above. Instead, it supports:
- -XX:+IdleTuningCompactOnIdle
- -XX:+IdleTuningGcOnIdle
- -XX:IdleTuningMinIdleWaitTime=180
- -Xjit:waitTimeToEnterDeepIdleMode=50000
Default JVM Options in AccuWeb.Cloud PaaS
By default, Accuweb.cloud PaaS uses G1 GC for JVM 8 and newer versions. For older versions, it uses ParNew GC. For JVM versions below 12, Accuweb.cloud adds the accuweb-cloud-gc-agent.jar to enable vertical scaling.
For JVM 12 and newer versions, the platform includes integrated vertical scaling to ensure G1 GC is triggered with these preset container variables:
- G1PERIODIC_GC_INTERVAL=3000: Interval between garbage collections in milliseconds (default is 15 minutes).
- GC_SYS_LOAD_THRESHOLD_RATE=0.3: Multiplier to adjust the G1PeriodicGCSystemLoadThreshold value.
- *G1PERIODIC_GC_SYS_LOAD_THRESHOLD={CPU_cores_number}GC_SYS_LOAD_THRESHOLD_RATE: Triggers garbage collection if the average one-minute system load is below this value. Ignored if set to zero.
You can check your Java process settings by running ps -ax | grep java. You will see something like this:
/usr/java/libericajdk-12.0.1/bin/java.orig -server -XX:G1PeriodicGCSystemLoadThreshold=0.6 -XX:G1PeriodicGCInterval=900k -XX:+UseStringDeduplication -XX:+UseG1GC -Xmaxf0.3 -Xminf0.1 -Xmx1638M -Xmn30M -Xms32M -jar Accuweb.cloud-helloworld-1.1.war
AccuWeb.Cloud automatically configures these parameters:
- Xmx: 80% of total available RAM in the container
- Xms: 32MB
- Xmn: 30MB
For JVM versions 12 and above, the platform also configures these Java options:
- G1PeriodicGCSystemLoadThreshold=CPU_COUNT*0.3: 30% of the load average based on the number of CPU cores available.
- G1PeriodicGCInterval=900k: 15 minutes between garbage collection pauses.
Customizing GC Settings in AccuWeb.Cloud PaaS
If you think adjusting the default settings can improve performance or memory usage, you can change them based on your application’s needs. Only do this if you understand the effects on your application.
Set custom GC parameters using Environment Variables (not Java options):
- _JAVA_OPTIONS and JAVA_TOOL_OPTIONS: Use these to change the default GC type. Example: _JAVA_OPTIONS=”-XX:+UseShenandoahGC”
- GC_DEF: Type of Garbage Collector. Example: GC_DEF=G1GC
- XMX_DEF_PERCENT: Percentage of RAM for XMX. Example: XMX_DEF_PERCENT=80
- XMX_DEF (or XMX): Maximum Java heap size. Example: XMX_DEF=1638 (for 2048MB RAM)
- XMS_DEF (or XMS): Initial Java heap size. Example:XMS=32M
- XMN_DEF: Size of the heap for the young generation. Example: XMN=30M
- G1PERIODIC_GC_INTERVAL (for openJDK 12/13 only): Frequency of G1 Periodic Collection in milliseconds. Example: G1PERIODIC_GC_INTERVAL=900 (15 minutes)
- G1PERIODIC_GC_SYS_LOAD_THRESHOLD (for openJDK 12/13 only): Allows G1 Periodic Collection if the system load is below this value. Example: G1PERIODIC_GC_SYS_LOAD_THRESHOLD={CPU_cores_number}*{GC_SYS_LOAD_THRESHOLD_RATE}
- GC_SYS_LOAD_THRESHOLD_RATE (for openJDK 12/13 only): Multiplier to adjust G1PeriodicGCSystemLoadThreshold. Example: GC_SYS_LOAD_THRESHOLD_RATE=0.3
- FULL_GC_AGENT_DEBUG: Enables or disables debug mode for tracking GC processes in logs. Example: FULL_GC_AGENT_DEBUG=true
- FULL_GC_PERIOD: Interval in seconds between full GC calls. Example: FULL_GC_PERIOD=900 (15 minutes)
- MAXPERMSIZE: Defined for JVM versions below 8 and RAM > 800MB. Example: MAXPERMSIZE=163 (calculated based on Xmx)
- XMINF_DEF: Minimum free space in the heap after GC to trigger heap expansion. Example: XMINF_DEF=0.1
- XMAXF_DEF: Controls heap compaction if free space exceeds this value. Example: XMAXF_DEF=0.3
You can also pass these parameters via the variables.conf file in the container.
Paths to config, executable, or log files vary by Java server and can be accessed via Configuration File Manager or SSH.
Step 1: Open configuration files to set up your Java server.
Step 2: For Tomcat, go to the opt > tomcat > conf > variables.conf file.
In this file, you can change default garbage collector settings or add a different one to replace the default (G1).
For example, if you want to use ShenandoahGC instead, just add it to the variables.conf file like this:
- -XX:+UseShenandoahGC
After this, your Java server will use only the specified garbage collector, regardless of allocated resources.
You can also adjust how JVM handles its heap memory with other JAVA options in this file.
Once properly configured, you can see the garbage collector in action on the Statistics tab.
That’s it! Enjoy better resource efficiency when running your Java apps in the cloud.