| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" |
| content="text/html; charset=windows-1252"> |
| <title>Java Application Profiling using TPTP</title> |
| <link rel="stylesheet" href="../default_style.css"> |
| </head> |
| <body link="#0000ff" vlink="#800080"> |
| <div align="right"> <font face="Times New Roman, Times, serif" |
| size="2">Copyright © 2006 International Business Machines Corp.</font> |
| <table border="0" cellpadding="2" cellspacing="0" width="100%"> |
| <tbody> |
| <tr> |
| <td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font |
| face="Arial,Helvetica"><font color="#ffffff"> Eclipse Corner |
| Article</font></font></b></td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| <div align="left"> |
| <h1><img src="images/Idea.jpg" align="middle" height="86" width="120"></h1> |
| </div> |
| <p> </p> |
| <h3>Java Application Profiling using TPTP<br> |
| </h3> |
| <blockquote> <b>Summary</b> <br> |
| <br> |
| The Eclipse Test & Performance Tools Platform (TPTP) Profiling tool |
| can be used to profile Eclipse plug-ins, |
| local Java(TM) |
| applications or complex applications running on multiple hosts and |
| different platforms. |
| The tool is tightly integrated with Eclipse, allowing profiling of |
| applications running from within Eclipse. <br> |
| This article demonstrates how |
| to use the TPTP Profiling tool to profile |
| a Java application for identifying execution related hot spots. It |
| shows |
| how to start the profiling session, use the various TPTP |
| views to analyze the data, identify methods with high execution time |
| then jump to the source code to fix the performance problem.<br> |
| <p><b> By Valentina Popescu, IBM<br> |
| <br> |
| </b> <font size="-1">February 21, 2006 (updated July 11, 2006)<br> |
| <br> |
| </font> </p> |
| </blockquote> |
| <hr width="100%"><br> |
| <h3>Profiling an Application<br> |
| </h3> |
| In the current environment of short development cycles for delivering a |
| product, developers tend to focus more on the functional aspects of |
| application execution, mostly via testing, debugging, and code fixing. |
| However, many problems do not easily surface until the application is |
| running in production mode, 24 hours a day, 7 days a week and gets |
| pushed to limits during some unexpected peak periods. <br> |
| <br> |
| The kinds of performance problems encountered in production cannot be |
| discovered during a |
| debugging |
| session. Before deployed and run in production mode, it is important to |
| use a Profiling tool to analyze application execution and identify |
| performance problems, such as execution |
| bottlenecks, object leaks, and system resource limitations.<br> |
| This article provides an introduction to the TPTP |
| Profiling |
| tool. It demonstrates how to use the TPTP Profiling tool to profile |
| a Java application in order to identify performance hot spots, |
| and fix and validate performance problems.<br> |
| <br> |
| <h3>TPTP Profiling Tool</h3> |
| The Eclipse Test & Performance Tools Platform <a |
| href="http://eclipse.org/tptp/">(TPTP)</a> Project |
| offers a profiling tool for identifying and isolating performance |
| problems such |
| as performance bottlenecks, object leaks and system resource limits. |
| The tool |
| targets applications of all levels of complexity, from simple |
| standalone <span |
| style="font-size: 12pt; font-family: "Times New Roman";">Java</span> |
| applications to Eclipse plug-ins or complex enterprise |
| applications running |
| on multiple |
| machines and on different platforms. |
| <br> |
| <br> |
| Being tightly integrated with the Eclipse project, the tool |
| is also easy to use and extend. That means that users can plug in their |
| preferred views to analyze the data, or can extend the data collection |
| metaphor |
| by implementing their own flavor of data collection agent.<br> |
| <br> |
| This article was written using the TPTP 4.2.0 based on the EMF 2.2.0 |
| and |
| XSD 2.2.0 release builds, which require Eclipse 3.2.0. You can download |
| these drivers from <a |
| href="http://www.eclipse.org/tptp/home/downloads/downloads.php?link=link1&ver=4.2.0">here</a>. |
| For TPTP 4.2.0 installation details go to the <a |
| href="http://www.eclipse.org/tptp/home/downloads/installguide/InstallGuide42.html">TPTP |
| download |
| page</a>.<br> |
| <br> |
| <br> |
| <h3>Profiling a Java application using TPTP<br> |
| </h3> |
| <div style="text-align: left;">The product catalog sample used in this |
| article |
| is a simple Java application that parses product |
| information stored in separate xml files and prints the result to the |
| console output. The file system location for the folder containing the |
| product xml files is passed as a program argument when running |
| the main class, <span style="font-style: italic;">Product.java</span>. |
| The xml files containing the product information are provided under the |
| section <a href="#RunningTheExample">running |
| the example</a>.<br> |
| <br> |
| <h4>Starting the application in profiling mode</h4> |
| After installing the sample application, the |
| first step is to run the product catalog application in profiling mode. |
| Profile |
| the application by using the <span style="font-style: italic;">Profile |
| As > Java Application</span> |
| popup-menu on the Product class as seen in the image below. <br> |
| <br> |
| </div> |
| <div style="text-align: center;"><img alt="" |
| title="Profile the Product application" |
| src="images/n_profileAction.jpg" style="width: 699px; height: 603px;"><br> |
| <br> |
| </div> |
| <p style="text-align: center;"><b style="">Figure |
| 1</b> Profile the <span style="font-style: italic;">Product catalog </span>Application<br> |
| <br> |
| </p> |
| <p style="text-align: left;"><img alt="" title="tip" |
| src="images/tip.gif" style="width: 62px; height: 13px;">Another way of |
| starting the application in profiling mode is to use the <span |
| style="font-style: italic;">Profile</span> |
| action available on the Java perspective's toolbar menu. Similar to |
| the |
| <span style="font-style: italic;">Run </span>and <span |
| style="font-style: italic;">Debug </span>toolbar actions, the <span |
| style="font-style: italic;">Profile </span>action will open the |
| launch configuration dialog and from there you can select the type of |
| application you want to profile.<br> |
| |
| <br> |
| </p> |
| <h4>Setting the Java program arguments</h4> |
| <p style="text-align: left;">The <span style="font-style: italic;">Profile |
| As > Java Application </span>action will open the launch |
| configuration wizard as displayed by Figure 2.</p> |
| <p style="text-align: left;">For this example, the folder |
| containing the product xml files is passed as a program |
| argument. As described in the Figure 2 below, set the program arguments |
| to be <span style="font-style: italic;">x:\myPath\products</span>, |
| where <span style="font-style: italic;">x:\myPath </span>is the path |
| where you have unzipped the folder containing the product xml files |
| provided at the end of this article.<br> |
| </p> |
| <div style="text-align: center;"><img alt="Program arguments" |
| title="Program arguments" src="images/args.gif" |
| style="width: 591px; height: 585px;"><br> |
| <br> |
| <span style="font-weight: bold;">Figure 2</span> <span |
| style="font-style: italic;">Product catalog</span> sample - program |
| arguments<br> |
| </div> |
| <p style="text-align: left;"><span style="font-weight: bold;"></span></p> |
| <h4><br> |
| </h4> |
| <h4>Setting profiling filters</h4> |
| The next step is |
| to set the profiling options to collect method execution information.<br> |
| To set these options, click the Monitor tab on the Launch Configuration |
| Properties wizard and select a set of profiling options that fits with |
| your performance investigation.<br> |
| <br> |
| <img alt="" src="images/tip.gif" style="width: 62px; height: 13px;">A |
| Profiling filter set is a |
| reusable set of profiling filters. |
| The purpose of creating profiling filter sets is to reuse them |
| during consecutive runs of the same application or to share them |
| between applications that require the same type of profiling |
| information.<br> |
| The steps below describe how to create a new filter set used to |
| profile the Product catalog application. We will be creating a new |
| filter set named ProductFilterSet which will be used to profile only |
| packages that have the |
| <span style="font-style: italic;">com.sample.product</span> prefix.<br> |
| <br> |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;">1. Choose to |
| collect execution details by |
| selecting the Execution Time Analysis option in the Monitor tab. <br> |
| <br> |
| </p> |
| <div style="text-align: center;"><img |
| alt="Execution Time Analysis option" |
| title="Execution Time Analysis option" src="images/execOption.gif" |
| style="width: 542px; height: 490px;"><br> |
| </div> |
| <p style="text-align: center;"><b style="">Figure 3</b> Execution Time |
| Analysis option<br> |
| </p> |
| <p style="text-align: left;">As shown in Figure 3 above we have |
| selected the Execution Time Analysis option that can be used during |
| consecutive runs of the |
| product catalog application. On the next run of this application, the <span |
| style="font-style: italic;">Setting Profiling Filters</span> step can |
| be skipped.<br> |
| <br> |
| </p> |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;">2. Select Edit |
| Options action to set the profiling execution options.</p> |
| <p style="margin-left: 1cm; text-indent: -0.5cm;">2a. Select the |
| "Collect |
| boundary classes excluded by the filter set" option and enter 3 as the |
| Boundary class depth value. </p> |
| <p style="margin-left: 1cm;">By selecting this option, you specify that |
| you want to collect |
| information for methods invoked to the specified depth starting with |
| the methods in your filter criteria.</p> |
| <p style="margin-left: 1cm;">As an example, let's assume that we have |
| set |
| the filter to collect information on method MyMethod and to filter out |
| methods |
| M1, M2, M3, M4.</p> |
| <p style="margin-left: 1cm;">If the following invocation stack is |
| executed: MyMethod > M1 > |
| M2 > M3 > M4 ( MyMethod invokes M1 which invokes M2 which invokes |
| M3 which invokes M4 ), based on the filtering criteria selected at |
| point 2a, the profiler will show this call stack: MyMethod > |
| M1 > M2 > M3 and will not display the last invocation M3 > M4 |
| (since this exceeds the specified depth of 3).</p> |
| <p style="text-align: center;"><img alt="Profiling Execution options" |
| title="Profiling Execution options" src="images/profOptions.gif" |
| style="width: 454px; height: 481px;"><br> |
| </p> |
| <p style="text-align: center;"><span style="font-weight: bold;">Figure 4</span> |
| Choose to collect execution information<br> |
| </p> |
| <br> |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;">3. Select the |
| classes to be profiled. <br> |
| </p> |
| <p style="margin-left: 0.5cm; text-indent: -0.5cm;"> |
| In the Monitor tab, select the Java Profiling item and double click or |
| select Edit Options action. The Filter Set wizard opens.<br> |
| Use the Filter Set page to choose the classes you want to profile. |
| There are a set of predefined filters available but for this sample you |
| will create a new filter set named ProductFilterSet which filters out |
| everything except packages prefixed by com.sample.product.<br> |
| Follow these steps to create the filter set:<br> |
| </p> |
| <p style="margin-left: 1cm; text-indent: -0.5cm;">3a) Select the Add... |
| action from the filter set list. In |
| the result dialog enter ProductFilterSet as the name of the new filter |
| then click OK</p> |
| <p style="margin-left: 1cm; text-indent: -0.5cm;">3b) Use the Add... |
| button from the Contents of selected |
| filter set list to create the two filters as shown in Figure 5.</p> |
| <br> |
| <div style="text-align: center;"><img |
| alt="Select the classes to be profiled" |
| title="Select the classes to be profiled" src="images/n_pSetP3.jpg" |
| style="width: 627px; height: 568px;"><br> |
| <br> |
| <span style="font-weight: bold;">Figure 5</span> Choose classes you |
| want to profile<br> |
| </div> |
| <div style="text-align: center;"><br> |
| <div style="text-align: left;"><br> |
| <h4>Run the application</h4> |
| </div> |
| </div> |
| <br> |
| Run the Product catalog application by pressing OK on the Launch |
| Configuration |
| wizard. Choose Yes when asked to switch to the Profiling and Logging |
| perspective.<br> |
| You should see the result of the program execution in the Console view, |
| similar with what is presented in Figure 6 below. <br> |
| <br> |
| <br> |
| <div style="text-align: center;"><img |
| alt="Product application terminated" |
| title="Product application terminated" src="images/n_profileApp.jpg" |
| style="width: 753px; height: 600px;"><br> |
| <b style=""><br> |
| Figure 6</b> Product catalog application has been executed<br> |
| <br> |
| <br> |
| <div style="text-align: left;"><img alt="" src="images/tip.gif" |
| style="width: 62px; height: 13px;"> The TPTP profiling tool allows you |
| to |
| interact with your profiled application. You can pause and resume |
| monitoring, run garbage collection on the profiled application, collect |
| object references or terminate the application.<br> |
| </div> |
| </div> |
| <span style="font-weight: bold;"><br> |
| <br> |
| </span> |
| <h4>Identify performance hot spots using the Execution Statistics view</h4> |
| <br> |
| Use the Execution Statistics view to identify performance hot spots. To |
| open this view, select the process in the Profiling Monitor |
| view and select Open with > Execution Statistics pop-up action.<br> |
| The Execution Statistic view shown in the Figure 7 below display the |
| methods executed, sorted by cumulative time. The cumulative time |
| for a method is the time spent to execute that method, including |
| any invocations to other methods.<br> |
| <br> |
| <br> |
| <div style="text-align: center;"><img alt="Execution statistics view" |
| title="Execution statistics view" src="images/n_executionStat.jpg" |
| style="width: 751px; height: 513px;"><br> |
| </div> |
| <div style="text-align: center;"><span |
| style="font-size: 12pt; font-family: "Times New Roman";"></span><br> |
| <span style="font-size: 12pt; font-family: "Times New Roman";"></span> |
| </div> |
| <p style="text-align: center;" class="MsoNormal"><b>Figure 7</b> |
| Execution |
| Statistics View<br> |
| </p> |
| As presented in Figure 4, the <b style="">Execution |
| Statistics</b> shows the main(java.lang.String[]), |
| readData(java.lang.String) and createParser() methods as the top three |
| methods with the highest execution time. It is not surprising to see |
| the main and readData methods on this list since the first one is the |
| starting point of the application execution while the second as |
| suggested by it's name, is reading the products data from the xml files.<br> |
| <br> |
| What comes as a surprise for us is the fact that createParser() |
| method, which |
| just creates a SAX parser instance used to parse |
| the xml files, has such a high execution time. The execution time for |
| this method accounts for 42.96% of |
| the application's total execution time. The Execution Statistics have |
| helped us to identify this method as a potential place to optimize the |
| application's performance.<br> |
| <br> |
| Once we have identified this, let's drill down and see the |
| createParser() method's execution details. <br> |
| <br> |
| <h4>Open Method Invocation Details view on the createParser() method<br> |
| </h4> |
| <br> |
| <div style="text-align: center;"> |
| <div style="text-align: left;">We will use next the Method Invocation |
| Details view to see what methods in the createParser() call stack are |
| responsible for the method's slow execution time. Open the Method |
| Invocation Details view by double-click on the createParser() method in |
| the Execution Statistics view.<br> |
| <br> |
| <br> |
| <div style="text-align: center;"><img alt="Method Invocation Details" |
| title="Method Invocation Details" src="images/n_mInv.jpg" |
| style="width: 844px; height: 705px;"><br> |
| <br> |
| <span style="font-weight: bold;">Figure 8</span> Method Invocation |
| Details view<br> |
| </div> |
| </div> |
| <br> |
| </div> |
| <br> |
| Figure 8 below presents the execution information for the |
| createParser() method. As you can see the method has been invoked once |
| by the readData(java.lang.String) method and invokes 5 different |
| methods. In the invoked methods table you can see that newSAXParser() |
| and newInstance() methods are responsible for the createParser's method |
| slow execution. These two methods were called 24 times, as the |
| createParser() method has been executed 24 times.<br> |
| <br> |
| <h4>Define a solution for the identified performance problem<br> |
| </h4> |
| <br> |
| By analyzing this data, we found that one way to improve the |
| createParser() execution time is to improve the execution of the two |
| SAXParserFactory methods. Since we have no control over these methods' |
| implementation, the only way to improve our application execution is to |
| reduce the number of calls we make to these methods.<br> |
| <br> |
| The solution is to create one parser instance and reuse it for parsing |
| all xml files, instead of creating a new parser for every file. Let's |
| open the source code and apply the fix.<br> |
| <p style="text-align: left;"><img alt="" title="tip" |
| src="images/tip.gif" style="width: 62px; height: 13px;">Before making |
| any such optimizations, make sure that they are supported by the code. |
| For example, while the SAXParser cannot be simultaneously used by |
| multiple threads, instances can be reused. Strictly speaking, instances |
| should be <code>reset()</code>before they are reused. It is also a |
| good idea to have a comprehensive set of unit tests in place before you |
| make changes to code that could possibly introduce changes in behavior.</p> |
| <br> |
| <h4>Open the source code and apply the performance fix</h4> |
| To open the source code for the createParser() method, select the |
| method in the Method Invocation Details view then right-click and |
| choose the Open Source action on the pop-up menu.<br> |
| <br> |
| <br> |
| <br> |
| <div style="text-align: center;"> |
| <div style="text-align: center;"><img alt="Source code" |
| title="Source code" src="images/n_sourceCode.jpg" |
| style="width: 815px; height: 693px;"><br> |
| </div> |
| <b><br> |
| Figure 9</b> Source code<br> |
| <br> |
| </div> |
| <p style="text-align: left;">Figure 9 shows the createParser() source |
| code. Notice that the method creates a new SAX parser instance on every |
| call.<br> |
| Update the source code as presented in Figure 10 below so that the code |
| will create only one parser instance and reuse it when parsing every |
| xml file.<br> |
| <br> |
| </p> |
| <p style="text-align: center;"><img alt="Source code" |
| title="Source code" src="images/n_sourceCodeFix.jpg" |
| style="width: 815px; height: 693px;"><br> |
| </p> |
| <p style="text-align: center;"><span style="font-weight: bold;">Figure |
| 10 </span>Source code fix<br> |
| </p> |
| <p style="text-align: left;">As presented in Figure 10, the performance |
| fix defines a global SAXParser instance. The createParser() method |
| initializes the parser and returns this instance every time the method |
| is |
| called.<br> |
| </p> |
| <p style="text-align: left;">Let's go back now and validate the fix by |
| running the Product catalog application in profiling mode once again.<br> |
| <br> |
| </p> |
| <h4>Validate the performance fix<br> |
| </h4> |
| <p style="text-align: left;">To validate the performance fix, select |
| the Product class in the Java perspective and as described above, |
| right-click and choose Profile As > Java Application.</p> |
| <p style="text-align: left;">The Profiling options wizard will not open |
| again as the previous profiling options will be used to run the |
| application. After the application is executed, open the Execution |
| Statistics view and compare the execution time.<br> |
| Figure 11 shows the execution times after the fix has been applied to |
| the code:<br> |
| </p> |
| <br> |
| <div style="text-align: center;"> |
| <div style="text-align: center;"><img alt="Execution Statistics view" |
| title="Execution Statistics view" src="images/n_executionStatFix.jpg" |
| style="width: 742px; height: 575px;"><br> |
| </div> |
| <br> |
| </div> |
| <div style="text-align: center;"><b style="">Figure 11</b> Execution |
| Statistics view<br> |
| </div> |
| <p style="text-align: left;"><br> |
| </p> |
| As you can see in the image above, the createParser() execution time is |
| now only 19% of the application execution, while before the performance |
| fix has been applied to the code, the createParser() execution time was |
| almost 43% of the application execution time.<br> |
| Note that this improvement will prove to be even more valuable as the |
| number of xml files to be parsed increases, so the fix will reduce the |
| application execution time exponential as more product files are being |
| added to the catalog.<br> |
| <br> |
| <h3>Conclusion</h3> |
| This article has shown how the TPTP profiling tool can be used to |
| identify and solve performance problems. There are more aspects of the |
| TPTP tool not covered by this article. If you would like to know more |
| about the tool's capabilities, there are a set of tutorial slides |
| and User Guides available <a |
| href="http://www.eclipse.org/tptp/home/documents/index.html">here</a>.<br> |
| <br> |
| <h3><a name="RunningTheExample"></a>Running the example</h3> |
| The file "<a href="productCatalogSample.zip">ProductCatalog_example.zip</a>" |
| contains the complete source code for the example in this article. |
| Extract the content of the ZIP file into the Eclipse "plugins" |
| directory. You will also need the list of product xml files which are |
| stored in the <a href="xmlProductFiles.zip">products.zip</a> file. |
| Extract the |
| content of the products.zip file to a desired location on your file |
| system and use this path as a program argument when running the Product |
| catalog |
| application.<br> |
| <br> |
| <p><small>Java and all Java-based trademarks and logos are trademarks |
| or registered trademarks of Sun Microsystems, Inc. in the United |
| States, other countries, or both.<br> |
| <br> |
| </small></p> |
| <br> |
| <br> |
| </body> |
| </html> |