October 21, 2016
Hot Topics:

Building in J2EE Performance during the Development Phase

  • July 7, 2006
  • By Steven Haines
  • Send Email »
  • More Articles »

Listing 3 rolls both of these test cases into a test suite that can be executed as one test.

Listing 3. MetricTestSuite.java

package com.javasrc.metric;

import junit.framework.Test;
import junit.framework.TestSuite;

public class MetricTestSuite
  public static Test suite()
    TestSuite suite = new TestSuite();
    suite.addTestSuite( DataPointTest.class );
    suite.addTestSuite( MetricTest.class );
    return suite;

A TestSuite exercises all tests in all classes added to it by calling the addTestSuite() method. A TestSuite can contain TestCases or TestSuites, so once you build a suite of test cases for your classes, a master test suite can include your suite and inherit all of your test cases.

The final step in this example is to execute either an individual test case or a test suite. After downloading JUnit from www.junit.org, add the junit.jar file to your CLASSPATH and then invoke either its command-line interface or GUI interface. The three classes that execute these tests are as follows:

  • junit.textui.TestRunner
  • junit.swingui.TestRunner
  • junit.awtui.TestRunner

And as these package names imply, textui is the command-line interface and swingui is the graphical interface. awtui provides a batch interface to executing unit tests. You can pass an individual test case or an entire test suite as an argument to the TestRunner class. For example, to execute the test suite that we created earlier, you would use this:

java junit.swingui.TestRunner com.javasrc.metric.MetricTestSuite

Unit Performance Testing

Unit performance testing has three aspects:

  • Memory profiling
  • Code profiling
  • Coverage profiling
  • This section explores each facet of performance profiling. I provide examples of what to look for and the step-by-step process to implement each type of testing.

    Memory Profiling

    Let’s first look at memory profiling. To illustrate how to determine if you do, in fact, have a memory leak, I modified the BEA MedRec application to capture the state of the environment every time an administrator logs in and to store that information in memory. My intent is to demonstrate how a simple tracking change left to its own devices can introduce a memory leak.

    The steps you need to perform on your code for each use are as follows:

    1. Request a garbage collection and take a snapshot of your heap.
    2. Perform your use case.
    3. Request a garbage collection and take another snapshot of your heap.
    4. Compare the two snapshots (the difference between them includes all objects remaining in the heap) and identify any unexpected loitering objects.
    5. For each suspect object, open the heap snapshot and track down where the object was created.

    A memory leak can be detected with a single execution of a use case or through a plethora of executions of a use case. In the latter case, the memory leak will scream out at you. So, while analyzing individual use cases is worthwhile, when searching for subtle memory leaks, executing your use case multiple times makes finding them easier.

    In this scenario, I performed steps 1 through 3 with a load tester that executed the MedRec administration login use case almost 500 times. Figure 1 shows the difference between the two heap snapshots.

    Figure 1. The snapshot difference between the heaps before and after executing the use case

    Figure 1 shows that my use case yielded 8,679 new objects added to the heap. Most of these objects are collection classes, and I suspect they are part of BEA’s infrastructure. I scanned this list looking for my code, which in this case consists of any class in the com.bea.medrec package. Filtering on those classes, I was interested to see a large number of com.bea.medrec.actions. SystemSnapShot instances, as shown in Figure 2.


    The screen shots in this article are from Quest Software’s JProbe and PerformaSure products.

    Figure 2. The snapshot difference between the heaps, filtered on my application packages

    Realize that rarely is a loitering object a single simple object; rather, it is typically a subgraph that maintains its own references. In this case, the SystemSnapShot class is a dummy class that holds a set of primitive type arrays with the names timestamp, memoryInfo, jdbcInfo, and threadDumps, but in a real-world scenario these arrays would be objects that reference other objects and so forth. By opening the second heap snapshot and looking at one of the SystemSnapShot instances, you can see all objects that it references. As shown in Figure 3, the SystemSnapShot class references four objects: timestamp, memoryInfo, jdbcInfo, and threadDumps. A loitering object, then, has a far greater impact than the object itself.

    Next, let’s look at the referrer tree. We repeatedly ask the following questions: What class is referencing the SystemSnapShot? What class is referencing that class? Eventually, we finally find one of our classes. Figure 4 shows that the SystemSnapShot class is referenced by an Object array that is referenced by an ArrayList that is finally referenced by the AdminLoginAction.

    Figure 3. The SystemSnapShot class references four objects: timestamp, memoryInfo, jdbcInfo, and threadDumps.

    Figure 4. Here we can see that the AdminLoginAction class created the SystemSnapShot, and that it stored it in an ArrayList.

    Finally, we can look into the AdminLoginAction code to see that it creates the new SystemSnapShot instance we are looking at and adds it to its cache in line 66, as shown in Figure 5.

    You need to perform this type of memory profiling test on your components during your performance unit testing. For each object that is left in the heap, you need to ask yourself whether or not you intended to leave it there. It’s OK to leave things on the heap as long as you know that they are there and you want them to be there. The purpose of this test is to identify and document potentially troublesome objects and objects that you forgot to clean up.

    Figure 5. The AdminLoginAction source code

    Page 3 of 4

    Comment and Contribute


    (Maximum characters: 1200). You have characters left.



    Enterprise Development Update

    Don't miss an article. Subscribe to our newsletter below.

    Sitemap | Contact Us

    Thanks for your registration, follow us on our social networks to keep up-to-date
    Rocket Fuel