Hero Image

How to Tune the Garbage Collector in Tomcat

How to Tune the Garbage Collector in Tomcat

The guys at PayPal famously experimented with alternatives to Java in search of performance gains. One important, but easily overlooked, way to keep your Java app performing at its best is to make sure that the JVM is well tuned to your needs - and that includes taming the Garbage Collector.​

If Java had true garbage collection, most programs would delete themselves upon execution.

  • Robert Sewell

Java’s Garbage Collector does an important job and, if you tune it properly, you can help prevent memory‑intensive programs from freezing your system. It is easy to assume that if you know how to develop large programs and applications, you already know how the Garbage Collection process works and that choosing a Garbage Collector algorithm means you fully understand the behaviour of the program you have developed.​

If you are not quite sure how the whole process works, the most important aspects are summarised below with a focus on current Java and Tomcat versions.​

Meet the Garbage Collector, it will save your day!

You have just developed a large application, and you could not be more excited. As this application runs it creates objects; as it continues to run, many of these objects are no longer required and they consume heap space until the JVM runs out of memory.​

This is where the Garbage Collector steps in: it identifies unreachable objects and recycles memory that it can prove will never be used again. This process is known as Garbage Collection (GC) and it avoids the need for the programmer to deallocate memory blocks explicitly, helping to reduce problems such as memory leaks, double frees and premature frees.​

However, GC activity can consume CPU cycles. You can influence how often GC runs and how long it pauses your application by adjusting heap sizing with the -Xmx and -Xms switches that control how the JVM handles its heap memory. Using -Xmx to start the JVM with an appropriate maximum heap size helps reduce the need for frequent heap expansions, and setting -Xms equal to -Xmx can avoid repeated heap resizing in long‑running server applications such as Tomcat.​

Java code does not explicitly specify a memory address and remove it in the program logic, so the Garbage Collector is responsible for finding unnecessary (garbage) objects and removing them.​

Understanding your code means understanding Garbage Collection

The GC manages heap memory, the portion of memory where dynamically allocated objects live. In modern HotSpot JVMs used with Java 17 and 21, the heap is split into regions that conceptually separate objects by age, typically grouped into a young generation and an old generation.​

Objects are created in the young generation and, once an object has survived a number of GC cycles, it is promoted to the old generation. The heap is created when the JVM starts and may increase or decrease in size while the application runs, depending on configuration and collector behaviour. When enough of the heap becomes occupied according to collector‑specific thresholds, garbage is collected; with an increasing number of objects, the number and cost of GC cycles also increases.​

To prevent GC from degrading application performance, it helps to keep the number of short‑lived temporary objects as low as practical, especially in high‑traffic web applications. This means that, before delving into GC tuning, you should consider optimising your code and object‑allocation patterns; if problems still exist under realistic load, then it is time to look carefully at GC configuration.​

Choose your favourite Garbage Collector on the Enscale platform

In current versions of the Enscale PaaS, the self‑scaling Java cloud hosting platform, the Garbage Collector can be tuned by the customer if desired.​

If no custom GC is specified for a Tomcat environment running on Java 21 or 25, the JVM uses CompressedOops. This default is chosen to provide a balance of throughput and predictable pause times for common server‑side workloads, and it is suitable for the majority of Tomcat‑based applications.​

On the platform, GC settings can be overridden using standard JVM startup flags so that you can explicitly select CompressedOops, G1GC, AdaptiveSizePolicy, or, where supported, collectors such as ZGC or Shenandoah for specialised use cases. The configuration is applied consistently regardless of how many cloudlets are actively used, so your choice of GC is not tied directly to the current instantaneous resource usage.​

For compatibility reasons, Enscale leaves most other JVM parameters at their defaults, with only slight tweaks to improve resource usage and scaling behaviour. Some of these options may affect performance and can be adjusted to suit a specific application; this is usually best done with full knowledge of the application by its developer, so you can tune further according to the needs of your particular application if required.​

You can set a custom GC (together with other JVM preferences, such as -Xmx and -Xms values) according to your own preference by editing the JVM options for your Tomcat node in the platform’s configuration (for example via variables.conf or the equivalent configuration entry in the Enscale dashboard).​

Enscale does the hard work

Before you reach the point where you might choose your own Garbage Collector, the Enscale development team has already invested effort to ensure that the defaults are going to help in the majority of cases.​

One of the most important characteristics that makes Enscale a distinctive platform, vertical scaling, introduces interesting challenges in choosing an appropriate default GC behaviour. Enscale measures RAM usage at the operating system level to provide a consistent approach for all server types (for example MySQL, PostgreSQL, caching servers and application servers), and this interacts with how the JVM reserves and releases heap memory.​

If an application starts with a modest heap footprint and later expands, the JVM typically does not return heap memory to the operating system immediately even if it becomes free again, which is a design trade‑off intended to make memory allocation faster for long‑running applications. This behaviour has implications for usage‑based billing models, so the platform’s defaults and scaling logic are selected to balance performance and resource efficiency for Java servers.​

The Enscale team evaluated several Garbage Collectors to see how they behave under vertical scaling, including the Serial, Parallel, Concurrent Mark Sweep (CMS) and G1 collectors, and documented their findings in a detailed article about PaaS vertical scaling. Although CMS is deprecated and removed in recent Java versions, the insights from those experiments helped inform how Compressed Oops is used today as a default with vertical scaling on the platform.​

In practice, this means that the Enscale PaaS is designed to give you a sensible platform to run your code on right out of the box, while still providing the versatility and freedom to customise GC configuration when more demanding workloads or specific application characteristics require it.​

The Enscale platform is intended to help you out, not get in the way.​

Set a custom Garbage Collector on Tomcat

To tune GC behaviour for a specific application, first create an environment with Tomcat (for example Tomcat 9, 10.1 or 11, depending on your application’s requirements) as the application server in your Enscale account.​

For this demonstration, VisualVM can be used to illustrate the active GC and heap behaviour; to connect directly to Tomcat from VisualVM, the environment needs a Public IP assigned.​

You can view the Public IP address in the dropdown list for the Tomcat node in the Enscale dashboard. VisualVM is a useful tool that allows you to observe Garbage Collection, thread activity, CPU and memory usage and more, and it is available as a standard tool in the Java ecosystem; Java Flight Recorder and Mission Control provide additional, more detailed insight on Java 21 and 25, but VisualVM remains convenient for quick inspections. Instructions for enabling remote monitoring with VisualVM in Enscale are provided in the platform documentation.​

Once connected, you can confirm which Garbage Collector is active by inspecting the monitoring views or JVM properties. On a Tomcat environment using Java 21 or 25 without explicit GC flags, you should see CompressedOops GC as the active collector by default; changing JVM startup options and restarting Tomcat allows you to verify the effect of selecting another supported collector or adjusting heap settings.​

To set a different GC in your Tomcat environment, navigate to the JVM options configuration for the server (for example, the variables.conf file in the server directory or the equivalent setting in the Enscale control panel) and add the relevant system properties. Examples include:​

  • -XX:+UseG1GC to explicitly select G1 GC (typically the default on Java 21).​
  • -XX:+UseParallelGC to select the Parallel collector for throughput‑oriented workloads where longer pauses are acceptable.​
  • On supported builds and Java versions, -XX:+UseZGC to enable the Z Garbage Collector for very low pause time requirements, noting its specific memory and version constraints.​

You can combine these with heap and pause‑time tuning flags such as -Xms, -Xmx and -XX:MaxGCPauseMillis, taking care to test under realistic load before applying changes to production environments. After saving the configuration, restart the Tomcat node so that the new options take effect, and restart your monitoring tool to confirm that the expected collector and settings are active.​

Conclusion

You may already know this joke:

Knock, knock.

“Who’s there?”

very long pause.

“Java.”

Modern Java is high performance and highly scalable, and the current GC implementations continue to improve with each release, but configuration still matters. By taking advantage of the flexibility offered by the Enscale platform to adjust JVM GC options and heap settings, you can align Tomcat’s behaviour more closely with your application’s allocation patterns and performance goals during your next performance audit.​

Do you have an account yet? You can create a new Enscale environment with Tomcat and try these settings on the Layershift platform using the current trial or entry options described on the hosting pages.​

Other Related Posts:

High Availability Is Important for Your Business

High Availability Is Important for Your Business

Companies are increasingly moving to cloud and hybrid models because their in-house IT teams, who used to just manage Exchange servers and desktops, often don't have the right tools, time, or specialised skills to run today's always-on platforms.

And even when businesses are already using the cloud, there's a huge difference between simply "being in the cloud" and actually having a high-availability architecture managed by experts. That distinction has become critical for business resilience.

2nd Feb 2026