Unexpected Full GCs Triggered by RMI in Latency-Sensitive Applications

We observed an unexpected increase in Full Garbage Collections (Full GCs) while optimising a latency-sensitive application with minimal object creation. Despite reducing the frequency of minor GCs to enhance performance, the system began to exhibit hourly periodic pauses due to Full GCs, which was counterintuitive.

Investigating the Source of Full GCs

Upon closer examination, we discovered that the Java Remote Method Invocation (RMI) system was initiating Full GCs every hour. Specifically, the RMI Distributed Garbage Collector (DGC) checks if a GC has occurred in the last hour and, if not, forces a Full GC. This behaviour occurs even if the application does not actively use RMI, leading to unnecessary performance overhead.

Understanding RMI's Impact on Garbage Collection

The RMI DGC collects periodic garbage to clean up unused remote objects. By default, it is configured to trigger a Full GC if none has occurred within a specified interval (defaulting to one hour). This mechanism ensures that stale references are collected in distributed applications. However, for applications that do not use RMI or where latency is critical, this can introduce unwelcome Full GCs.

Configuring RMI DGC Intervals

To mitigate this issue, we can adjust the intervals at which the RMI DGC checks for garbage collection. This is done by setting the following JVM options:

-Dsun.rmi.dgc.client.gcInterval=86400000
-Dsun.rmi.dgc.server.gcInterval=86400000

The values are in milliseconds, so setting them to 86400000 extends the interval to 24 hours. It's important to note that the client and server intervals must be increased; adjusting only one has no effect due to how RMI DGC schedules its checks.

Applying the Solution

By updating these JVM options, we observed a significant reduction in unnecessary Full GCs. Our application's latency improved as the unexpected pauses caused by the RMI DGC were eliminated.

Performance Considerations

While extending the RMI DGC intervals mitigates the issue for non-RMI applications, be cautious if your application uses RMI. Increasing the intervals might delay the cleanup of unused remote objects, potentially leading to memory leaks or other resource management issues.

Conclusion

Unanticipated behaviours like RMI-induced Full GCs can impact application performance, especially in latency-sensitive systems. You must be aware of default JVM settings that may not align with your application's needs. Adjusting the sun.rmi.dgc.client.gcInterval and sun.rmi.dgc.server.gcInterval options can help optimise garbage collection behaviour.

Have You Experienced Similar Issues?

Have you encountered unexpected Full GCs in your applications? How did you address them? Share your experiences and insights below.

About the Author

Peter Lawrey is the CEO of Chronicle Software

Comments

Popular posts from this blog

Java is Very Fast, If You Don’t Create Many Objects

System wide unique nanosecond timestamps

Comparing Approaches to Durability in Low Latency Messaging Queues