You observe a pattern of explicit garbage collection on a regular interval (usually every 60 seconds), but the application does not contain any System.gc() calls. The problem might be Remote Method Invocation (RMI) distributed garbage collection.
Excessive garbage collection affects Java™ Virtual Machine (JVM) performance.
Resolving The Problem
RMI uses a distributed garbage collection (DGC) algorithm that depends on regular garbage collection (GC) activity to determine if remote objects are candidates for collection. It helps with automatic memory management when remote objects are stored in memory. More information can be found at the links below:
Understanding distributed garbage collection (IBM SDK 7.0 / 7.1)
Understanding distributed garbage collection (IBM SDK 6.0)
To ensure that the remote objects are collected in a timely fashion, RMI takes the step of triggering a System.gc() on a regular interval. However, in most cases regular GC activity is sufficient for effective DGC.
Example of verboseGC data that shows 60 second garbage collection intervals based on timestamps:
|<GC(385): Bytes Traced =0 (Foreground: 0+ Background: 0) State = 3 >|
<GC(385): mark stack overflow>
<GC(385): GC cycle started Wed May 24 00:17:39 2006
<GC(385): heap layout: (321330848/429495496) (107373880/107373880) /0>
<GC(385): freed 6288024 bytes, 79% free (428704728/536869376), in 1075 ms>
<GC(385): mark: 161 ms, sweep: 19 ms, compact: 895 ms>
<GC(385): refs: soft 0 (age >= 32), weak 2, final 167, phantom 0>
<GC(385): moved 43776 objects, 3486944 bytes, reason=16>
<GC(386): Bytes Traced =0 (Foreground: 0+ Background: 0) State = 3 >
<GC(386): GC cycle started Wed May 24 00:18:40 2006
<GC(386): heap layout: (321320752/429495496) (107373880/107373880) /0>
<GC(386): freed 6286376 bytes, 79% free (428694632/536869376), in 1041 ms>
<GC(386): mark: 128 ms, sweep: 19 ms, compact: 894 ms>
<GC(386): refs: soft 0 (age >= 32), weak 2, final 170, phantom 0>
<GC(386): moved 21831 objects, 2667880 bytes, reason=16>
Generic JVM Arguments
You will need to set the JVM arguments below from the Administration Console. This will require a restart of your server. For detailed instructions, please read the technote Where to set generic JVM arguments in WebSphere Application Server .
- RMI Garbage Collection Interval
Add the following two arguments to adjust the interval between RMI initiated garbage collection events, which will set the time interval between full garbage collections that are forced by the DGC:
VALUE is in milliseconds. For example 60000 = 60 seconds.
Setting value to 3600000 (one hour) is recommended if you are already seeing periodic full GCs every minute.
Defaults for Java 1.4.2 and Java 5.0 are 60000 milliseconds (one minute)
This was increased to 3600000 milliseconds (one hour) in Java 6.0 and later.
Disabling Explicit Garbage Collections
Add the following to disable explicit System.gc() calls:
IBM SDK supplied in WebSphere Application Server on AIX, Linux, Windows
JDK supplied in WebSphere Application Server versions on Solaris and HP-UX
Frequently Asked Questions
Does disabling explicit garbage collections stop all System.gc() calls?
The behavior depends if you are using the IBM SDK or Sun Java JDK.
- IBM SDK (AIX, Linux, Windows)
When you disable explicit GC calls on the IBM SDK, all calls to System.gc() are ignored. This includes full GCs triggered by heapdump generation, direct byte buffer usage, and manual calls to System.gc().
The only exception is for RMI because a different mechanism is used to trigger the garbage collection cycles.
Sun Java JDK (Solaris and HP-UX)
No. The behavior is a bit different since a slightly different API is used. Your application calls to System.gc() will be ignored, but any internal methods in the standard Java libraries, including NIO (New I/O) and RMI, will still be executed.
More information can be found in Java Bug 5025281 .
Do both server and client arguments need to be added?
The two sun.rmi arguments reflect whether your JVM is running in server or client mode. Depending on the version of your SDK, either mode can be set as the default. It is best to set both options so the argument will be picked up by the JVM.
Why do I still have full GCs occurring?
The arguments above only affect full GCs related to the distributed garbage collector and explicit GCs that are kicked off by application code, respectively. Full GCs can still occur even with these options enabled, usually when the heap (or tenured/old regions) become full.
Problems with excessive full GCs may indicate a completely different issue that is not covered by this document, which can include memory exhaustion, performance issues, among others.
Was this topic helpful?
15 June 2018