Visualising JVM Memory and garbage collections

Sometimes it can be useful to understand how Java uses the memory we give it with the -Xms and -Xmx parameters.  Here we will show you how to configure Tomcat to expose the relevant data to standard interfaces and how to view this data.

Assumptions:

  • You have Tomcat 8.5 or later installed in the default location of /opt/tomcat

  • You are running Java version 1.8 or later

  • You have a user that can sudo (or access to root)

  • JAVA_HOME is defined correctly

  • Your firewall is disabled (or you know how to allow traffic through it)

Step 1: VisualVM

On your workstation, install VisualVM - You can find it here: https://visualvm.github.io/

Step 2: Install the visualGC plugin into VisualVM

  1. Run Java VisualVM, and click “Tools > Plugins”.

  2. Click the “Available Plugins” tab and check “Visual GC” in the list.

  3. Click the “Install” button and follow the installation screen to finish.



Step 3: Configure JMX on your tomcat server.

One enables JMX by adding a few options to the JVM command-line.  Note that the example below does not implement encryption nor require authentication.

The best place to do this is the setenv.sh (or .bat) script which is in the /opt/tomcat/bin directory.  This is what my setenv.sh looks like:

CATALINA_OPTS="" CATALINA_OPTS=" $CATALINA_OPTS -Dcom.sun.management.jmxremote " CATALINA_OPTS=" $CATALINA_OPTS -Dcom.sun.management.jmxremote.port=9000 " CATALINA_OPTS=" $CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false " CATALINA_OPTS=" $CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false " CATALINA_OPTS=" $CATALINA_OPTS -Dcom.sun.management.jmxremote.local.only=false " CATALINA_OPTS=" $CATALINA_OPTS -Djava.rmi.server.hostname=192.168.178.99 " export CATALINA_OPTS

 

If the setenv.sh file does not exist, please create it.  If you’ve had to create it and you’re running on Linux, please change the ownership of the file to tomcat:tomcat and change the mode of the file (i.e. the permissions) to 755: 

chown tomcat:tomcat /opt/tomcat/bin/setenv.sh chmod 755 /opt/tomcat/bin/setenv.sh

Note that you can choose any unused port, though 9000 is very common.  If you change the port you will need to ensure that the port is not used and note the number as it will be used to tell VisualVM how to connect.

For the change to take effect, you will need to restart tomcat.

Step 4: Start jstatd

Jstatd is … “The jstatd tool is an RMI server application that monitors for the creation and termination of instrumented HotSpot Java virtual machines (JVMs) and provides an interface to allow remote monitoring tools to attach to JVMs running on the local host.”  It comes as standard with the Java JDK and will give us insight into some aspects of Tomcat’s JVM.

 

For this exercise, we will run jstatd manually, though instructions can be found on the internet to run jstatd permanently as a service.  This, however, is outside the scope of this document.

 

Jstatd will create its own RMI Server with its own security policies.  And it will need to have at least one policy which we will define here:



Create a file in a reasonable (and memorable?) location such as your $JAVA_HOME directory with the name jstatd.all.policy.  Edit that file and put this content in it:

grant codebase "file:${java.home}/../lib/tools.jar" {          permission java.security.AllPermission; };

Again ensure that the file has appropriate ownership and mode - If unsure, change the ownership and mode as we did (above) for the setenv.sh file.

You will need to choose a port on which jstatd will create its internal RMI registry.  This needs to be an available port.  For this exercise, we will use 1099.

To start jstad manually:

Jstatd will continue to run until you stop it with Control-C.

 

Step 5: Start monitoring with VisualVM and VisualGC

Start VisualVM.

Right-click on Remote and select Add Remote Host

 

In the pop-up, select “Advanced Settings”

In the Advanced Add Remote Host window, enter the IP address (or resolvable name) of your host and give it a friendly name then click OK.

 

This will create the remote host in VisualVM:



After around 1 minute, the host will acquire extra information:



Double-clicking on Tomcat fills-in the right-hand side of the window:



Clicking on the Visual GC tab gives you a view info how the Tomcat memory is being used and managed by the garbage collector:

 

One thing of note is that when VisualVM is working or struggling to connect to the JVM(s), it may seem unresponsive for up to 2 minutes.