Skip to main content

View statistics on Apache Geronimo via the JVM

Michael Galpin, Software Engineer, Vitria Technology
Michael Galpin holds a degree in mathematics from the California Institute of Technology. He has been a Java developer since the late 1990s and is a software engineer for Vitria Technology, in Sunnyvale, CA.

Summary:  The Apache Geronimo application server is not only open source, it's high performance. So it's a natural choice for running your high-performance applications. However, just running your application in Geronimo doesn't guarantee it will satisfy your performance requirements. At some point you probably need to analyze and optimize the efficiency of your application. There are plenty of tools available for this task, but you can accomplish a lot of it by analyzing the Java™ Virtual Machine (JVM) statistics. Find out how to get statistics from the JVM so you can profile your application and optimize it to meet your performance needs.

Date:  11 Apr 2006
Level:  Introductory
Activity:  714 views

JVM statistics

The JVM provides many statistics. These statistics dispense data on the basic JVM features, such as Just-In-Time (JIT) compilation, class loading, memory allocation, and most interestingly, garbage collection.

Just-In-Time compilation

The JVM performs JIT compilation of byte code into machine code. This action is similar to that of an interpreter like you might use for a scripting language such as Perl. It's more advanced, however, providing many optimizations that allow interpreted byte code to run nearly as fast (sometimes faster) than precompiled code. Obviously there's overhead in performing JIT compilations. Two useful statistics for measuring how much overhead your application will encounter are the number of JIT compiles and the total amount of time spent performing these compilations. (See Resources for more details on JIT compilation.)

Class loading

The JVM is responsible for loading the classes in your application and classes from libraries that your application's classes use. Thus these could be classes loaded from WARs or EARs that you have deployed in Geronimo, JAR files included in your WAR or EAR, or classes from JARs loaded by the Geronimo container. The JVM can also choose to unload classes if the class has not been used for an extended period of time. This leads to several important statistics: how many classes have been loaded, how many have been unloaded, and how much time has been spent loading and unloading classes.

Memory (Heap) allocation

There is no malloc() function in Java technology because the JVM automatically allocates memory for objects. Objects are allocated from the heap; thus the amount of heap memory both used and free are two very important statistics. Monitoring your heap allocation is one of the simplest ways to detect a dreaded memory leak.

Garbage collection

This is probably the most interesting statistic from the JVM. Just as the JVM allocates memory for your objects, it also reclaims this memory on objects that are no longer being used. There are many interesting reads on how garbage collection works, including the different algorithms you can instruct the JVM to use for its garbage collector.

There are also many interesting statistics about the garbage collector itself. The first is how often the garbage collector has been called and how much time was spent during garbage collection. Garbage collection has a lot of overhead, as it basically halts the execution of your application so it can examine your objects. Obviously, a lot of garbage collection can really slow down your application.

Other interesting statistics have to do with object generations. The garbage collector sorts objects by generation, with each generation denoting a certain number of garbage collections the object has survived. (An object that has survived numerous garbage collections is less likely to be garbage collected than an object that has survived none or few garbage collections.) Sorting objects like this allows the garbage collector to examine fewer objects, making each garbage collection quicker. Thus, the number of objects in each generation can be extremely interesting, providing an even better way to look for memory leaks and a great way to examine the impact of potential optimizations, such as object caching and pooling.


Access JVM statistics

There are several JVM implementations available, but the most common one is Sun's HotSpot JVM (see Resources for a link to the technology). Starting with Java 2 Platform, Standard Edition (J2SE) 1.4.2, HotSpot was fully instrumented, providing many of the useful statistics described above. There are several ways to get this data and analyze it. After you've gotten to the statistics generated by the JVM, you can access Geronimo's JVM and analyze your applications.

Access methods

The simplest way to get to some of the JVM stats is via the command line. HotSpot recognizes many command line options, several of which allow you to customize heap size and garbage collection options. You can also use the -verbose:gc option. This causes the JVM to print out lines that look like this:

[GC 70333K->65666K(98896K), 0.0007817 secs]
[Full GC 65666K->59333K(98896K), 0.0205250 secs]



The first line in the example above indicates a garbage collection occurred. A total of 70,333KB were used on the heap before the collection, and 65,666KB after. The first line also indicates that there are 98,896KB of total available space. Finally, it indicates how much time the garbage collection took -- also the amount of time your application was halted. The next line indicates the same information, but denotes a full garbage collection. A full garbage collection involves the JVM examining all objects on the heap, including those that have survived many generations, that would not be analyzed on partial garbage collections.

For even more detailed information, use the -XX:+PrintGCDetails and -XX:+PrintGCTimeStamps options. These options provide detailed information on the different generations of objects on the heap.

For something more visually interesting, you can use a specialized tool. Both open source and commercial tools are available. You can also use some tools provided by Sun for use with HotSpot. The jvmstat project contains several tools for monitoring JVM statistics. It includes a graphical tool called the Visual Garbage Collector or visualgc. It's relatively simple to use. You need Java 5 or later to run jvmstat, although it can attach and monitor any 1.4.2 or later JVM. Simply download it and unzip it (see Resources for the download link). Add it to your path, and you're ready to go. When you have a Java process started, use the jps tool to identify its JVM by typing jps. It gives you a list of running Java processes with an ID for their JVMs. You then invoke visualgc with the ID of the process you want to monitor. The jvmstat distribution includes a shell script for invoking visualgc. This works well on *nix or on Microsoft® Windows® if you have something like cygwin installed. Alternatively, you can invoke it as follows:

java -Xbootclasspath/p:%JAVA_HOME%\lib\tools.jar -jar %JVMSTAT_HOME%\jars\visualgc.jar 316



Here, the JAVA_HOME environment variable specifies where the JDK is installed, and JVMSTAT_HOME indicates where the jvmstat package is installed. The 316 on the end of the line is the ID for the JVM you want to monitor. The jvmstat package also includes a jstat tool. It provides much of the same information seen in visualgc but outputs it as text. This is great for collecting statistics that you can then drop into another program to do deep analysis on, generate reports on, and so on. This article concentrates on the visualization of these statistics using visualgc.

Listing 1 provides a short program you can run to test monitoring with jvmstat.


Listing 1. Test monitoring with jvmstat
StatGen.java
import java.util.ArrayList;
import java.util.List;

public class StatGen {

    static final int MAX_BLOCK = 8*1024*100;

    public static void main(String[] args) {
        try{
            int numLoops = 1;
            if (args.length > 0){
                 numLoops = Integer.parseInt(args[0]);
            }
            System.out.println("#loops="+numLoops);
            
            List<long[]> list = new ArrayList<long[]>(numLoops);
            for (int i=0;i<numLoops;i++){
                int sz = (int) (Math.random()*MAX_BLOCK);
                long[] garbage = new long[sz];
                if (sz % 5 == 0){
                    list.add(garbage);
                }
                System.out.println("Sleeping 0.5s");
                Thread.sleep(500);
            }
            System.out.println("Done");
        } catch (Throwable t) {
              t.printStackTrace();
        }
        System.exit(0);
    }
}

This is a simple program. It uses generics, so you'll need Java 5. You can easily alter it to not use generics if you like, then it will run with older JDKs. It causes memory allocation by creating randomly sized arrays of long integers. It mimics a memory leak by randomly placing some of these arrays (~20% of them) into a list. Thus the garbage collector can reclaim most of the memory allocated on each loop, but it can't reclaim the arrays that are added to the list. You can play with some of the parameters, such as the sleep size and maximum block size. It also takes a command line parameter so you can easily tell it how many loops to execute.

After you've compiled StatGen, you can start simply with java StatGen 100. This executes 100 loops. Remember, you can specify minimum and maximum heap size on the command line. Picking different minimum and maximum heap sizes will have a distinctive visual effect when running visualgc. You can also specify different garbage collection algorithms; you should get a good understanding of the differences in these algorithms when monitoring StatGen with visualgc.

Figure 1 shows some sample output of running visualgc with StatGen.


Figure 1. Running visualgc with StatGen
Running visualgc with StatGen

Figure 2 shows the most interesting of the windows. It first shows JIT compilations. In this case, there were only three, not surprising for such a simple example. It also shows class loader information -- again, this is simple because the application is so simple.


Figure 2. Basic JVM information and heap usage
Basic JVM information and heap usage

Next it shows overall garbage collection stats. You see 123 collections and a total of about 0.3 seconds spent doing garbage collection. From the first graph, you see the application had been running for about 100 seconds, so 0.3% of that time had been spent doing garbage collection.

There are also stats on the different generations. The eden space shows new objects that have never been through garbage collection. The sample code generates a lot of those, and they are quickly collected.

Notice the two survivor spaces. These are basically smaller sets of objects that have survived a few garbage collections. All of your objects are either immediately ready for collection or are never ready, so if they make it to a survivor space, they'll quickly graduate from it.

Next is the older generation. These objects have survived numerous garbage collections. You can see the steady rise, indicative of a potential memory leak. Finally, you see the permanent generation of objects that the JVM is certain will never be collected.

The histogram window (see Figure 3) shows data on survivor spaces -- not a lot going on here.


Figure 3. Histogram window showing data on survivor spaces
Histogram window showing data on survivor spaces

Geronimo and the initial build

There are several directories in the binary and source installations you downloaded earlier. The binary download includes the bare bones of Geronimo necessary to run and use Geronimo. The source download includes all the Geronimo source, including Maven build scripts to build the entire tree. First, take a look at the binary distribution and then the source distribution.

JVM statistics on Geronimo sample applications

Geronimo comes with several sample Web applications. Now that you have some tools for extracting JVM statistics from any JVM, it's easy to do this for Geronimo apps.

Start Geronimo

It's pretty interesting just to start Geronimo and monitor it with visualgc, as shown in Figure 4, Figure 5, and Figure 6.


Figure 4. Starting Geronimo and monitoring with visualgc
Starting Geronimo and monitoring with visualgc

Figure 5. Graph showing JIT compilations, class loader information, and garbage collection
Graph showing JIT compilations, class loader information, and garbage collection

Figure 6. Survivor Age Histogram
Survivor Age Histogram

Starting Geronimo was done with the standard java -jar %GERONIMO_HOME%/bin/server.jar command. You can gain some immediate insight by just using the -server option on your startup command, as shown in Figure 7.


Figure 7. Using the -server option on your startup command
Using the -server option on your startup command

Notice there are much fewer JIT compilations. That's because more classes get loaded when the JVM starts up when you use the -server option. The default startup mode is designed for quicker startup to accommodate desktop applications.

In both cases, you see a lot of long-running objects on the heap, but the number flattens out once Geronimo is completely started. This shows all the server objects being loaded, such as the various GBeans and the services they manage. The Geronimo developers will be pleased to see no signs of a memory leak though, as the old generation and permanent generation allocations flatten out.

Sample Web applications

Now you can also run some of the included Geronimo Web applications. The graph in Figure 8 shows the garbage collection action for the JSPX-XHTML sample application.


Figure 8. Garbage collection action for the JSPX-XHTML sample application
garbage collection action for the JSPX-XHTML sample application

You can see the sudden rise of objects on the left, and then most of them disappear after the page is rendered, as you would expect. You can see the JIT compilations and class-loading events that also corresponded to the application running.

Now that you've seen how to access and analyze the JVM statistics generated when running one of Geronimo's sample Web applications, you can start analyzing your own applications. It's just a matter of starting up Geronimo, starting up visualgc, and then deploying and/or starting your application. Run some events through it, watch it load classes, compile bytecode, and of course, manage memory.


Summary

JVM statistics are invaluable when tuning an application. The tools provided by Sun let you quickly analyze your application, make optimizations, and see the effects of your optimizations. They also allow for experimentation with various JVM options to perform additional tuning to the application. One of the goals of Geronimo is to provide a high-performance application server, and JVM statistical analysis is a great complement in your quest for maximum application performance.


Resources

Learn

Get products and technologies

About the author

Michael Galpin holds a degree in mathematics from the California Institute of Technology. He has been a Java developer since the late 1990s and is a software engineer for Vitria Technology, in Sunnyvale, CA.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Java technology, WebSphere
ArticleID=107390
ArticleTitle=View statistics on Apache Geronimo via the JVM
publish-date=04112006
author1-email=mike.sr@gmail.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers