NetBeans IDE 4.0 Profiler Tutorial

This article is intended to be used in conjuction with NetBeans Profiler, Milestone 5.

The NetBeans Profiler is a powerful tool that provides important information about the runtime behavior of your application. While imposing relatively little overhead, the NetBeans Profiler tracks CPU performance and memory usage. This tutorial will show you how to use the Profiler with NetBeans 4.0 to:

Portions of this tutorial originally appeared in a June, 2004 Java Developer's Journal article (http://sys-con.com/story/?storyid=45081&DE=1) about JFluid, the underlying technology used by the NetBeans Profiler. All reprinted material is used by permission of the publisher of Java Developer's Journal.

This tutorial should take approximately one hour to complete.

Setting Up Your Environment



Installing the Profiler

The NetBeans Profiler is in beta and is available as a separate download. To use this tutorial you must install the most recent version of the NetBeans Profiler. Be sure to follow the NetBeans Profiler Download & Install instructions.

Configuring Tomcat

Profiling a web application requires that the web server be run with the JDK that is included with the NetBeans Profiler. So to use the Profiler with the Tomcat server that is bundled with NetBeans a small change to the way Tomcat starts is necessary. The easiest way to do this is to modify the script that starts Tomcat. The script is catalina.bat (on Windows) or catalina.sh (on Unix). These scripts are located in Tomcat's bin folder; a typical location on a Windows system would be:

  C:\Program Files\netbeans-4.0\nb4.0\jakarta-tomcat-5.0.28\bin\catalina.bat
And on Unix the location will be something like:
  /export/home/gs/tools/netbeans/40/nb4.0/jakarta-tomcat-5.0.28/bin/catalina.sh
  1. Save a copy of the script as a backup.
  2. Right below the large block of comments that is at the top of the file, add a line that sets JAVA_HOME to the folder that contains the JDK included with the NetBeans Profiler. Choose Profiler > Help > About Profiler in NetBeans to display the folder name. Example value on Windows:
        set JAVA_HOME=c:\Documents and Settings\gs\.netbeans\4.0\modules\profiler-ea-vm\
    Example value on Unix:
        JAVA_HOME="/home/gs/.netbeans/4.0/modules/profiler-ea-vm/"
    

Obtaining the required source files

This tutorial uses a web application based on the HelloWeb project created in the NetBeans IDE 4.0 Quick Start Guide for Web Applications. The modifications for this tutorial include the addition of a servlet that handles the incoming request. It creates a Java bean and then dispatches to the JSP that creates the response. The servlet has been poorly written on purpose in order to highlight features of the NetBeans Profiler.

You get all application files from the ProfilingTutorial.zip file.

  1. In your file system, create a folder for the unzipped application files. From now on, this folder will be referred to as $UNZIPHOME.
  2. Click here to download the ProfilingTutorial.zip file.
  3. Use an application that unzips files to unzip the ProfilingTutorial.zip file to $UNZIPHOME.
  4. $UNZIPHOME now has web and src folders. The web folder contains the two JSP files and the deployment descriptors. The src folder contains the source files for the servlet and Java bean classes.

Creating a Project



Creating a web project from the provided source files

  1. Choose File > New Project (Ctrl-Shift-N). Under Categories, select Web. Under Projects, select Web Project with Existing Sources. Click Next.
  2. In Location, click Browse to select the web application's document root. The document root is $UNZIPHOME, the folder to which you unzipped the ProfilingTutorial.zip file.
  3. In Project Name, type ProfilingTutorial. Click Next.
  4. Click Finish. The IDE creates the $UNZIPHOME/nbproject project folder and the $UNZIPHOME/build.xml file. The ProfilingTutorial project opens in the IDE. You can view its logical structure in the Projects window and its file structure in the Files window.
  5. This final step is only required when NetBeans is configured to use JDK v5 as the default Java Platform.

    1. The current Profiler only supports .class files created by JDK v1.4.2, so if you have not installed a v1.4.2 JDK and configured it as a NetBeans Java Platform, you will need to do so. Note that in its beta release the NetBeans Profiler installs a JDK based on v1.4.2 - you set it as JAVA_HOME up in the Configuring Tomcat step. For more information refer to the online Profiler help.

    2. In the Projects window right-click the ProfilingTutorial entry and choose Properties. Select a Java Platform that uses the v.1.4.2 JDK and then click the OK button.
    3. In the Tomcat bin folder, make a backup copy of catalina.50.bat (on Windows) or catalina.50.sh (on Unix).
    4. Make the same edit to catalina.50.bat (on Windows) or catalina.50.sh (on Unix) that you made in the Configuring Tomcat step.

Running the Project

  1. In the Projects window right-click the ProfilingTutorial entry and choose Clean and Build Project. Then right-click the ProfilingTutorial entry again and choose Run Project. This will cause the IDE to build the project, start Tomcat, and then display the index.jsp page in a browser window.
  2. Verify that Tomcat started correctly by clicking the Bundled Tomcat tab in the IDE's Output window. Scroll to the top of the Tomcat output to verify that Tomcat was started with the NetBeans Profiler JVM. Examine the line that begins with Using JAVA_HOME; the Java home should be the folder that contains the NetBeans Profiler JVM. If Tomcat does not start or the JAVA_HOME is not the directory that contains the NetBeans Profiler JVM, then verify that you followed the instructions in the Configuring Tomcat step. Sample output for Windows is illustrated below.

    View Tomcat output - click for full size image

  3. A browser window should have opened and displayed the http://localhost:8084/ProfilingTutorial/ page. Verify that the web application is working by typing NetBeans User into the name field and clicking the OK button. The result should be similar to the illustration below. View Application Output

Monitoring Runtime Behavior



Attaching to a Running Application

Now that you have verified that Tomcat is using the JVM included with the NetBeans Profiler you can attach the IDE's profiling tools to that JVM and monitor its runtime behavior.

  1. Choose Profile > Attach Profiler. The Specify Attach Settings dialog is displayed.
  2. For Attach To: choose J2EE Web/App Server
  3. For Running on: click the This Computer radio button
  4. For Attach Settings click the Dynamic Attachment radion button and then click the Select Running VM radio button. Select the Tomcat entry (typically org.apache.catalina.startup.Bootstrap start) from the list of VMs.
  5. In Working Directory type the fully qualified name of Tomcat's bin folder. As an example, a typical value on a Windows system would be:
      C:\Program Files\netbeans-4.0\nb4.0\jakarta-tomcat-5.0.28\bin
    And on Unix the value will be something like:
      /export/home/gs/tools/netbeans/40/nb4.0/jakarta-tomcat-5.0.28/bin
  6. Click the OK button. The Attach and Profile dialog is displayed.
  7. Click the large Monitor Application button. Make sure that the Enable Threads Monitoring option is not checked.
  8. Click the Attach button.

Interpreting the Monitor Graphs

The NetBeans Profiler displays three graphs in the output window, as illustrated below.

View Monitor Graphs - click for full size image

The graph on the left is the easiest to understand. The red shading indicates the allocated size of the JVM heap, updated approximately once per second. The purple overlay indicates the amount of heap space actually in use. In the example above the allocated heap size at the last update was almost 14 megabytes. Of that 14 megabytes a little over 4 megabytes is actually being used to hold Java objects.

The graph on the right is also easy to understand. It merely shows the count of active threads in the JVM, updated approximately once per second.

The graph in the center is the most interesting. It shows two important heap statistics.

  • The blue line is the percentage of execution time spent by the JVM doing garbage collection and is graphed against the y-axis on the right edge of the graph. Time spent by the JVM doing garbage collection is time that is not available for it to run your application. So if the blue line indicates a large percentage you may want to consider tuning the JVM by configuring a larger heap size (refer to the -Xmx parameter documentation) or perhaps switching to a different garbage collection algorithm.
  • The red line is surviving generations and is graphed against the y-axis scale on the left edge of the graph. The count of surviving generations is the number of different ages of all the Java objects on the JVM's heap, where "age" is defined as the number of garbage collections that an object has survived. When the value for surviving generations is low it indicates that most of the objects on the heap have been around about the same amount of time. If, however, the value for surviving generations is increasing at a high rate over time then it indicates your application is allocating new objects while maintaining references to many of the older objects it already allocated. If those older objects are in fact no longer needed then your application is wasting (or "leaking") memory.
Clicking the View Telemetry Graphs Button button will cause the IDE to display larger versions of the three graphs in the main display window.

Determining CPU Time Used by a Method



Switching to Performance Analysis Mode

The Profiler is attached to the Tomcat JVM, but is only monitoring high level statistics. To find out detailed information about the performance of a specific method (or methods) in the application you will need to modify the Profiler's settings.

  1. Click the View Modify Profiling Button button or choose Profile > Modify Profiling.

  2. Click the Analyze Performance button.

  3. Select the Part of Application radio button. Then click the Select button that is next to the Part of Application radio button.

  4. Click the Add button.

  5. Click the Select button. The Profiler displays the Select Class tree.

  6. Expand the ProfilingTutorial entry by clicking its plus sign icon.

  7. Expand the Source Packages entry by clicking its plus sign icon.

  8. Expand the org.me.hello entry.

  9. Expand the RequestHandler.java entry.

  10. Click the RequestHandler entry and then click the OK button.

  11. The methods in the RequestHandler class are now displayed in the Select Methods dialog as illustrated below. Click the processRequest method and then click the OK button.

    View Select Methods Dialog

  12. Select the processRequest method by clicking on it in the list of Root Methods and then click the OK button. You have just selected processRequest as the root method for performance analysis. This means that the processRequest method and all methods that it calls, and all methods that they in turn call (and so on) will be monitored. Starting from processRequest, the Profiler does analysis of the method call graph to determine which methods need profiling. Only those methods are profiled - the rest of your application will continue to run at full speed with no profiling overhead.

  13. Click the OK button on the Modify Profiling dialog.

Running the Profiled Method

Now that you have chosen processRequest as a root method you need to use the portion of the web application that causes that root method to run. This is easy to do because the processRequest method handles all requests from the index.jsp page.

  1. In your web browser click the Back button to return to the http://localhost:8084/ProfilingTutorial/ page.

  2. Click the OK button to resubmit "NetBeans User" as your user name. It will take a bit longer before the response appears because the Profiler is monitoring performance of the processRequest method.
  3. After Hello, NetBeans User! displays in your browser, click the View CurrentResults Button button or choose Profile > Get Current Results.

Interpreting the Performance Analysis Graphs

The Profiler displays the latest performance results, as illustrated below.

View Performance Results - click for full size image

The top window shows the complete method call graph beginning with the root method. The processRequest method ran for 168 milliseconds (ms). Note, however, that very little time was spent running the instructions of the processRequest method itself - the sixth line in the window shows the "self time" for processRequest to be only 0.421 ms. The vast majority of the time was spent in methods called by processRequest. In particular, the forward method took up 84.7% of the execution time. This is not surprising given the amount of work the forward method has been given to do.

The power of the NetBeans Profiler is it helps you identify bottlenecks in your code that were not expected or that will prevent your application from scaling well. Note that the createUniqueID method took up 11.3% of the execution time. You can click the plus sign next to the createUniqueID entry to investigate exactly where the time went. If you examine the source code for createUniqueID you will discover it uses a hideously inefficient algorithm that should be redesigned.

The bottom window is a flatter depiction - it shows the "self time" for each method in the call graph.


Monitoring the Creation of Objects



Switching to Memory Analysis Mode

The Profiler can do detailed analysis (also referred to as instrumentation) of CPU performance or memory usage, but it cannot do both at the same time. To find out detailed information about the allocation and garbage collection of objects on the JVM's heap you will need to modify the Profiler's settings.

  1. Click the View Modify Profiling Button button or choose Profile > Modify Profiling.

  2. Click the Analyze Memory Usage button.

  3. Select the Record both object creation and garbage collection radio button.

  4. Click the OK button.

Running the Profiled Application

Now that you have chosen analyze memory usage you need to use the web application in order to determine whether it is using memory efficiently.

  1. In your web browser click the Back button to return to the http://localhost:8084/ProfilingTutorial/ page.

  2. Click the OK button to resubmit "NetBeans User" as your user name.

  3. After Hello, NetBeans User! displays in your browser, click the browser's Back button to return to the previous page.

  4. Repeat steps 2 through 3 nine times. Repeated submission of the same user name is necessary for this demonstration.

  5. Click the View CurrentResults Button button or choose Profile > Get Current Results.

  6. The Profiler displays the latest memory analysis results in a table. Click the Class Name column to sort the rows by class name.

  7. Scroll down through the table rows until the row for the org.me.hello.NameHandler class is displayed.

Interpreting the Memory Analysis Graphs

The illustration below shows the statistics for the org.me.hello.NameHandler class.

View Memory Results - click for full size image

The columns provide object allocation and memory usage information.

  • Total alloc. obj. (on the far right) is easiest to understand. This is the total count of all objects of this class that have been created. For the NameHandler class this value is 10, which is the number of times you pressed the Ok button on the web application's form.

  • Allocated Objects is the number of objects that the Profiler is actually monitoring. In this example, of the 10 instances of NameHandler that have been created the Profiler is only monitoring 1 of those instances. By default this number will be approximately ten percent of the value of total allocated objects (so the numbers you see might vary a bit from the illustration). By monitoring only a subset of the created objects the Profiler is able to dramatically reduce the overhead it places on the JVM, which then allows your application to run at close to full speed.

  • Live Objects is the number of the Allocated Objects that are still on the JVM's heap and are therefore taking up memory.

  • The two Live Bytes columns show the amount of heap memory being used by the Live Objects. One column displays a graph, the other displays text.

  • The Age Average value is calculated using the Live Objects. The age of each object is the number of garbage collections that it has survived. The sum of the ages divided by the number of Live Objects is the Age Average.

  • The Generations value is calculated using the Live Objects. As with Age Average, the age of an object is the number of garbage collections it has survived. The Generations value is the number of different ages for the Live Objects.

You can use this information to help track down memory leaks. The value for Generations is the same as the Surviving Generations value described in the Interpreting the Monitor Graphs section, but restricted to the objects of a single class. This finer granularity of monitoring can help you find the specific objects that are wasting heap space.

In this example, though, you do not even need Generations to see a problem with the NameHandler class. The Total alloc. obj. value is 10. The intent of the servlet code was to reuse NameHandler objects when the same user name is entered. Clearly, that is not happening. The bug is in the processRequest method: the key used to check for an entry in the Map is not the same as the key used to store the entry. The result is a pretty typical Java memory leak: an object is placed into a Map and then forgotten.

Another handy tool for understanding application behavior is to see where in your code the objects of a particular class are being allocated. This can often provide clues about why an object is still on the heap. The NetBeans Profiler will display stack traces for any class if you right-click the class's entry in the table and choose Show Allocations Stack Traces.

To end the profiling session, choose Profile > Detach.


Exploring Further



This tutorial has just scratched the surface of the Profiler's many powerful features. Refer to the NetBeans Profiler help file for more information on these topics.

  • When profiling CPU usage a class filter can be defined to prevent the profiling of methods outside your application (for example all methods in java.*). This helps keep your application running at closer to full speed.
  • Profiling CPU usage can interfere with the JVM's bytecode optimizations, causing the reported CPU times to not match real world performance. Techniques are available though for minimizing the Profiler's affect.
  • The Analyze Memory Usage feature can be limited to monitoring just object allocation. This will decrease the Profiler's impact on performance.
  • If when analyzing memory usage you discover that only a few classes seem to be causing problems, you can disable the monitoring of objects of all other classes.
  • Features are available that will monitor your application's startup time or a specific code fragment in your application.
  • Detailed thread statistics are available.
  • Remote profiling - profile an application that is running on a different machine.
By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo