Apache Tomcat is a Java servlet container, and is run on a Java Virtual Machine, or JVM. Tomcat utilizes the Java servlet specification to execute servlets generated by requests, often with the help of JSP pages, allowing dynamic content to be generated much more efficiently than with a CGI script.
If you want to run a high-performing installation of Tomcat, taking some time to learn about your JVM is essential. In this article, we'll learn how Tomcat and the JVM interact, look at a few of the different JVMs available, explain how to tune the JVM for better performance, and provide information about some of the tools available for monitoring your JVM's performance.
How Tomcat interacts with the JVM
Utilizing servlets allows the JVM to handle each request within a separate Java thread, as each servlet is in fact a standard Java class, with special elements that allow it to respond to HTTP requests.
Tomcat's main function is to pass HTTP requests to the correct components to serve them, and return the dynamically generated results to the correct location after the JVM has processed them. If the JVM can't efficiently serve the requests Tomcat passes to it, Tomcat's performance will be negatively affected.
Choosing the right JVM
There are many JVMs to choose from, and Tomcat runs on many of them, from open source projects such as Sun Microsystem's HotSpot or Apache Harmony, to proprietary JVMs like Azul VM.
Despite the wide variety of available JVM flavors, the majority of Tomcat users favor Sun Microsystem's HotSpot JVM, because its just-in-time compilation and adaptive optimization features are particularly suited for efficiently handling Tomcat's servlet requests.
So for the majority of Tomcat users, HotSpot is the JVM to use. However, if you are attracted a feature that is specific to a certain JDK, there is nothing wrong with installing Tomcat on two different JVMs and running some benchmarks to see which solution is best for your needs. In the end, it's a balancing act. Choose the JVM that provides the best balance of performance and features for your site.
How to configure Tomcat's Default JVM preferences
Once you decide on a JVM and install it on your server, configuring Tomcat to run on it is a very simple process. Simply edit catalina.sh, found in Tomcat's bin folder, and change the JAVA_HOME environment variable to the directory of your chosen JVM's JDK. When you restart Tomcat, it will be running on your new JVM.
Optimizing your JVM for best performance
The better your JVM performs, the better your installation of Tomcat will perform. It's as simple as that. Getting the most out of your JVM is a matter of configuring its settings to match your real-world performance needs as closely as possible. Update your JVM to the latest version, establish some accurate benchmarks so you have a way of quantifying any changes you make, and then get down to business.
Effective memory management
The main thing to consider when tuning your JVM for Tomcat performance is how to avoid wasting memory and draining your server's power to process requests. Certain automatic JVM processes, such as garbage collection and memory reallocation, can chew through memory if they occur more frequently than necessary. You can make sure these processes only occur when they need to by using the JAVA_OPTS -Xmx and -Xms switches to control how JVM handles its heap memory.
If your JVM is invoking garbage collection too frequently, use the -Xmx switch to start the JVM with a higher maximum heap memory. This will free up CPU time for the processes you really care about.
To get even more out of this change, you can include the -Xms switch. This switch makes the JVM's initial heap memory size equal to the maximum allocated memory. This means the JVM will never have to reallocate more memory, a costly process that can eat up power you want being used to serve incoming requests.
If your web applications can handle a lower garbage collection throughput, you can also experiment with the -Xincgc switch, which enables incremental garbage collection. This means that rather than halting in place to perform garbage collection tasks, the JVM will execute garbage collection in small phases.
It can be tricky to determine the most balanced configuration for your site's needs. Fortunately, there's an easy way to capture data on how your JVM is handling garbage collection. Simply use the -verbose:gc switch to generate logs you can use to help you arrive at the best solution.
Next, let's take a look at the way your JVM handles threads. There are two types of Java threads - green and native. Native threads are scheduled by your OS, while green threads are managed entirely within the user space of your Java Virtual Machine. If your JVM supports both, you should try both models to determine the best choice for your site.
Generally, native threads offer the best performance, especially if you are running a lot of I/O bound applications (which is very likely, since you are running Tomcat). However, green threads outperform native threads in some specific areas, such as synchronization and thread activation. Try both and see which option gives you the biggest performance boost.
Managing your JVM
Tuning for performance is not a finite process. Usage situations change over time, and problems that are not immediately apparent can expose themselves over a longer period of time. There are a number of tools available to help you keep an eye on your JVM's performance.
One of the most convenient solution is VisualVM, a tool that is packaged with the JDK, and can provide you with great performance statistics. Other commonly used JVM monitoring tools included with the SDK include console, jps, and jstack. Run regular tests on your JVM to make sure its configuration still suits your needs, and you can be sure that your Tomcat instances will always perform at their best!