Garbage Collector Performance under Load - Web Performance

Garbage Collector Performance under Load

The overwhelming majority of dynamic internet-facing applications are built on garbage collected runtimes such as Java and .NET.  Garbage collection is popular because it promotes rapid application development.  On the other hand, whenever a system is demonstrating unexpectedly poor performance, the garbage collector invariably surfaces as a possible suspect.  Our advanced server analysis module even hooks into garbage collection performance monitoring on the .NET platform.

The reality, however, is that modern garbage collectors are very good.

Fact: Our company has been in business since 1999.  In this time, no one can recall ever encountering a system with a performance problem that could primarily be attributed to poor garbage collector performance in the absense of any other resource constraint.

In general, there are two variables that impact the overhead of a modern, precise, multi-generational garbage collector: pause duration and collection frequency.

As a rough rule, garbage collector pause durations are proportional to the number of live objects in the heap. If, at the beginning of a collection event, there are 1000 objects, and ten are live, then the GC merely needs to traverse the ten live objects and copy their handles into a new allocation table.  If all 1000 objects are live, then the GC needs to traverse all of them and frees no memory for the effort.

Collection frequency is proportional to the rate at which objects are created and inversely proportional to the amount of free memory. This makes intuitive sense: if we have infinite memory, then we never need to perform garbage collection.  If we have nearly zero memory, then the garbage collector will run on every allocation request.

If we double the amount of free memory, we can create twice as many objects before we need to run a collection — but the collection does not necessarily take any longer to complete.

High garbage collection overhead is, almost without exception, a symptom of insufficient free memory. Rapidly creating objects, in and of itself, will not necessarily cause significant garbage collection overhead — this is the use case for which modern GCs are optimized.

Garbage collection is performed by the CPU. Web infrastructure that is not already saturated can “catch up” after a brief delaying event such as  a garbage collection in a way that is not discernible to casual end-users.  If a web application is not showing 100% utilization on at least one processor core, then its performance is not actually being impacted by the garbage collector.

Garbage collection is sometimes serial. This is in principle a problem for newer many-core web servers.  Data structures that don’t lend themselves to parallelism can’t be garbage collected in parallel, either.  The particular GC algorithm you use may have a significant impact on many-core systems.

Conclusion: The takeaway here is that garbage collection fails in a small number of fairly specific ways, and that poor garbage collection performance is usually symptomatic of a hardware resource constraint.  We should be careful not to assume that performance problems can be explained away by the ordinary function of the garbage collector.

— Lane, engineer at Web Performance.

Further reading:

Add Your Comment

You must be logged in to post a comment.


Copyright © 2024 Web Performance, Inc.

A Durham web design company


(1) 919-845-7601 9AM-5PM EST

Just complete this form and we will get back to you as soon as possible with a quote. Please note: Technical support questions should be posted to our online support system.

About You
How Many Concurrent Users