+ All Categories
Home > Documents > Performance Tuning Essentials for Java and...

Performance Tuning Essentials for Java and...

Date post: 11-May-2020
Category:
Upload: others
View: 20 times
Download: 0 times
Share this document with a friend
13
Performance Tuning Essentials for J2SE and J2EE Minimize memory leaks with Borland ® Optimizeit Suite Jay Campan, Senior Software Engineer Eric Muller, Director Business Development Borland Software Corporation March 2002 Introduction: why performance tuning is crucial for Java To create a Java program that is functionally perfect yet runs horribly slow is to create a Java program that... runs horribly slow. Borland ® Optimizeit Suite provides developers with a complete solution for managing application performance. In light of today’s compressed development cycles, multi-tiered architectures, and complex technologies, many organizations are challenged to get stable enterprise applications out the door in a timely manner. Devoting a small amount of energy throughout the development process to address and correct performance obstacles dramatically lowers the risks and costs associated with poorly performing applications over the life of the code. Java performance tuning simply means optimizing your code for speed, reliability, scalability, and maintainability. Producing truly scalable, lightening-fast J2SE and J2EE applications demands clarity of purpose and well-understood programming priorities. A major benefit of adopting regular performance tuning is instantly seeing exactly which parts of your applications represent important bottlenecks and which are behaving efficiently. Table of Contents Introduction 1 Address Book J2EE application example 3 Finding and fixing memory issues 4 Conclusion: performance tuning is crucial for Java 9 Appendix A 10 Appendix B 11 Appendix C 13
Transcript
Page 1: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Performance TuningEssentials for J2SE™

and J2EE™

Minimize memory leaks withBorland® Optimizeit™ Suite

Jay Campan, Senior Software Engineer

Eric Muller, Director Business Development

Borland Software Corporation

March 2002

Introduction: why performance tuning iscrucial for Java™

To create a Java™ program that is functionally perfect yet runs

horribly slow is to create a Java program that... runs horribly slow.

Borland® Optimizeit™ Suite provides developers with a complete

solution for managing application performance.

In light of today’s compressed development cycles, multi-tiered

architectures, and complex technologies, many organizations are

challenged to get stable enterprise applications out the door in a

timely manner. Devoting a small amount of energy throughout the

development process to address and correct performance obstacles

dramatically lowers the risks and costs associated with poorly

performing applications over the life of the code.

Java performance tuning simply means optimizing your code for

speed, reliability, scalability, and maintainability. Producing truly

scalable, lightening-fast J2SE™ and J2EE™ applications demands

clarity of purpose and well-understood programming priorities. A

major benefit of adopting regular performance tuning is instantly

seeing exactly which parts of your applications represent important

bottlenecks and which are behaving efficiently.

Table of ContentsIntroduction 1

Address Book J2EE™ application example 3

Finding and fixing memory issues 4

Conclusion: performance tuningis crucial for Java™ 9

Appendix A 10

Appendix B 11

Appendix C 13

Page 2: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

2

Performance tuning: a developmentbest practice

A major strength of Java is its platform-independent byte-code

approach and automatic handling of garbage collection. Unlike in

C/C++, developers are able to focus on an application’s business

requirements and largely are free from platform considerations.

Experienced developers, however, do not focus exclusively on

application functionality. The reality is that below this level of

abstraction, hard limitations of memory and processing power

exist, as do the patterns and constraints of garbage collection,

thread scheduling, and a host of other considerations managed by

the Java virtual machine (JVM™) and the operating system below it.

Successful developers—and productive development processes—

incorporate regular use of performance analysis from the earliest

stage of code creation throughout the development process, into

QA testing, and beyond. Regualr frontline checking and testing of

small modules of code by the principal author is a proven way to

assure that the Java applications produced will be fast, reliable, and

scalable.

Not all code is worth optimizingThe latest generation of application servers bring increased

memory and processing power to the party. Yet sheer hardware

alone can never overcome truly flawed code. A single buggy line

ripples forward and can cause application-wide bottlenecks or can

mysteriously trigger disasterous crashes once an application is in

production.

The developer’s challenge is that it can be almost impossible to

know which part of a J2SE or J2EE application is causing a speed

bottleneck or memory issue. The strength of Java and the J2SE and

J2EE platforms is the high level of abstraction, re-use of objects,

and insulation from layers of processing and system interpretations.

But while encapsulation is great for shielding you from vast lower-

level complexities, it also leaves you with few clues about where to

focus your performance attention.

Tools are needed that extend your intuition and let you effortlessly

see and understand how your J2SE or J2EE application behaves

when it is running. Many years ago Stanford Computer Science

Emeritus Professor Donald Knuth famously warned that

prematurely optimizing code can lead to wasted effort and poor

program architecture. This caution remains true. In fact, the danger

is not only in prematurely optimizing, but in misguided

optimization in general—focusing on unimportant aspects of the

code, or rebuilding the code based on flawed or restricted logic.

With the advent of highly abstracted, object-oriented languages

such as Java, Knuth raised the related concern that programmers

are in danger of losing touch with the factors determining whether

their code will run and scale well: “At first you try to ignore the

details of what’s happening at the lower levels. But when you’re

debugging, you can’t afford to be too compartmentalized. You

can’t afford to only see things at the highest level of abstraction.”

Performance tools allow you to be smart and efficientabout optimizingKnuth advises that developers need insight about what’s going on

below the surface if their code is to be scalable, reliable, and fast.

The Optimizeit™ Suite of tools are designed to efficiently give

developers easy-to-understand, powerful views into the Java virtual

machine, granting just this kind of insight.

A fundamental question is: “What are the priority performance

issues for this module or application?” Tools like Borland®

Optimizeit™ Suite, specifically designed for Java performance

tuning, offer an ideal way to answer this question—and be assured

that your improvements are informed and efficient. Without tools

to help prioritize key Java trouble areas, you are likely to spend

time micro-optimizing unimportant sections at the expense of

addressing issues that actually drive your application’s overall

performance.

The goal ought to be for each member of the development team to

be equipped with the tools to be smart about performance tuning

each step of the way. Smart performance tuning will take place in

the context of an application’s overall business requirements. Some

Page 3: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

3

tiny performance issues simply may not warrant improvement

efforts. Other, important optimizing trade-offs will arise only when

components are brought together, at which point an understanding

of the overall architecture will guide modifications.

Achieving fast, reliable codeSo what are the causes of poor performance? Three crucial

performance issues for Java programs are: excessive use of

temporary objects, Java memory leaks, and speed bottlenecks

due to poor CPU utilization. This paper focuses on Java memory

leaks, which are responsible for both slow speed and poor

reliability. Classic memory leaks as experienced in C/C++ are not

possible in Java, yet Java memory leaks are quite real and

potentially quite troublesome. Because Java memory leaks are

different than C/C++ leaks, tools designed specifically for Java are

best suited to spotting and fixing them.

Tuning your code for speed and performance iteratively, as you

develop and bring modules of code together, is the best way to

minimize frantic troubleshooting sessions at the end of a project—

or, worse, in production, where even small problems are

transformed into costly, complex challenges. The tuned

applications delivered to QA and to customers will instead be

lightweight, stable, scalable, and screamingly fast.

Address Book J2EE™ applicationexampleThe Address Book J2EE application example is a basic Web

application that has been developed for the purpose of this test

case. The application allows users to search for contact information

stored in an address book. A user can decide to add a person to a

list of selected contacts. The list of contacts is available and can be

displayed until the user closes the session.

The application uses only servlet components for the sake of

simplicity and ease of deployment. The address book data is

contained in a XML file, and the Address Book J2EE application

example uses the SAX API (Simple API for XML) to retrieve the

information from the XML file when needed.

For this example, Address Book WAR files are available for

download from http://www.optimizeit.com

Similar Borland® Optimizeit™ Suite performance tuning guides—

using the same J2EE application example— takes you through the

steps of troubleshooting speed bottlenecks due to poor CPU

utilization as well as problems due to excessive temporary object

allocations. The Optimizeit™ Profiler (the tool used in each of

these examples) integrates easily into your development

environment and the intuitive GUI will have you expertly

troubleshooting memory leaks and performance bottlenecks in

minutes.

Before you begin

Before exploring the test case, you will need to complete a few

preparation steps. To get ready, make sure you have:

• Installed an application server. If you have not installed an

application server, you may download and install the

Tomcat server for free from http:// jakarta.apache.org

• Integrated Optimizeit™ Profiler with your application

server. Appendix A provides a guide for doing this.

• Deployed the Address Book J2EE application example in

your application server. Appendix B provides a guide for

doing this.

• Launched your application server from within Optimizeit

Profiler.

• Attached Optimizeit Profiler to your application server.

Once these steps have been performed, your application server and

Optimizeit Profiler will be running. Optimizeit Profiler will be

displaying the Heap View (showing a number of red bars). At this

Page 4: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

4

point, you should be able to access the Address Book J2EE

application example from your browser using a URL similar to

http://localhost/addressbook/enter

Note: you may have to modify the URL if your application server

uses a port other than the default of 80. If the server uses the port

8080, for example, then the URL to use becomes

http://localhost:8080/addressbook/enter

If you have a problem with any of these preparation steps,

Appendix C provides a troubleshooting guide.

Finding and fixing memory leaksIf you are familiar with C/C++ development, you are probably well

aware of memory leaks. These languages do not have a garbage

collector, so it is the sole responsibility of the programmer to free

memory when an object is no longer necessary. Memory leaks

occur when you forget to free an object and lose the reference to

the object. Because you no longer have access to the object, you

have no way to free it. Each time such a leak is re-created,

additional memory is used and not freed. Eventually, the process

that runs the application will run out of memory and crash.

The good news in Java is that all unreferenced objects are

automatically freed by the garbage collector, so memory leaks

similar to C/C++ memory leaks simply cannot happen. The bad

news, however, is that situations may arise where an object is

indeed no longer used, but some reference to it somewhere

perseveres. If you are not aware of the reference, and do not

explicitly remove it (example: an object is cached in a hashtable and

referenced by a listener) then the object will not be garbage

collected—and you have a Java memory leak. Memory leaks in Java

are sometimes called “dangling references” or “loitering objects.”

What are the symptoms of a memory leak?If you have a memory leak in your application, then each time the

leaking code is exercised, more memory in the heap will be used by

the leaked objects. Over time, the heap grows crowded with

loitering objects, and garbage collection becomes a more arduous

process. With most virtual machines, when the garbage collector

runs, all the threads of your application are stopped. The latest

generation of the virtual machine, such as Sun® JDK® 1.4, permit

the option of running concurrent garbage collection. In any case, if

the garbage collector is run often, or needs to run for a long time,

an application will run correspondingly slower.

The cycle of poor performance will continue to spiral downward.

Because of the increasing size of the heap, the virtual machine will

trigger the garbage collector more often, causing performance to

suffer more. The large heap may also cause paging at the OS level,

further slowing down the application. In the end, the virtual

machine may eventually run out of memory and crash with an Out

Of Memory exception. Most application servers will automatically

restart the virtual machine if it crashes, so service to users is not

interrupted. But the extra drag on the garbage collection process

will assure that the application’s performance is substandard.

How to track memory leaks with theOptimizeit™ Profiler Tracking memory leaks without the aid of a tool like the

Optimizeit Profiler is a challenging undertaking. The Optimizeit

Profiler offers several features that make memory leak tracking

easy, even for large applications, allowing you to probe and

pinpoint the offending line(s) of code.

Let’s look to the Address Book J2EE application example. It has

been designed to present symptoms of a memory leak. Namely,

after stressful testing of the application, response times becomes

increasingly long. Eventually, after the application has run for some

time, the virtual machine runs out of memory and crashes.

To track down this memory leak—or any memory leak in your

own application—simply follow these five steps: (1.) Isolate the

action responsible for the memory leak; (2.) Determine which are

the leaked objects; (3.) Find out why the code is leaking; (4.)

Pinpoint the line of code causing the leak; and (5.) Correct it.

Page 5: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

5

Isolating the action responsible for the memory leak The first step in tracking a memory leak is to understand which

action in the application is causing the leak.

1. In the Optimizeit Profiler, click on the Show VM Infos

button to switch to the virtual machine information

view. This view shows you information about the current

state of the virtual machine. Focus on the chart on the top

left, which displays the size of the Java heap (memory used

by the Java objects in the virtual machine). The green line

shows the current size of the heap. The red line shows the

maximum size of the heap.

2. Click the Run garbage collector button on the tool

bar to get rid of any garbage collectable or “any objects that

can be garbage collected” objects. The current size of the

heap (green bar) should decrease. Note the current value.

3. From the browser, access the Address Book main page at

http://localhost/ addressbook1/enter. We are going to

exercise the application and try to isolate the leak.

4. In the first-name text field on the page, enter Doug then

click Start search. After few seconds, the name of the

contacts are displayed in the browser. Notice that under

each person’s name there is a link “Add to my contacts.”

This allows you to add this person to your list of contacts.

You can perform several searches and add different people

to your contact list. At any time, you can see your contact

list by clicking “Show my contact list.” The list of contacts

is discarded when you click “Close my session” or when the

servlet session times—out after 30 minutes of inactivity.

5. Click Add all persons to contacts to add all the people

found (people named Doug) to your list of contacts. Then

click on Back to search to come back to the search view.

Search for people whose first name is Stephanie. Again add

all the people found to your contact list by clicking the Add

all persons to contacts link. Then click Close my session.

6. At this point, come back in the Optimizeit Profiler and click

again the button Run garbage collector to get rid of

all unreferenced objects. Now notice the size of the current

heap. You will see a difference of more than 100 Kb from

the value you noted in Step 2. What the growth in the heap

size tells you is that somehow performing various searches,

adding people to the contact list and closing the session has

resulted in objects being created and not garbage collected.

We know that performing searches and closing a session

should not create permanent objects—this should make us

suspicious that we have a memory leak. If you repeat Steps

3 through 6, you will see the heap continues to grow,

confirming that there is indeed a leak.

Determining which are the leaked objectsSo we have now discovered that performing a search, adding

people to the contact list, and closing the session is causing a

memory leak, and eventually this leak threatens to crash the virtual

machine. Let’s now focus on how to find the leaked objects.

1. First, close any existing session (if the page displays a Close

my session link, click it). The browser should show

Welcome to VMGEAR address book! and the

default search page.

2. Click the Show memory profiler button on the tool

bar to return to the memory profiler. You should see the

Heap View (view with the horizontal red bars). If you do

not see the red bars, click the Show heap button on the

tool bar. Click the Run garbage collector button, and then

on the Mark current instance count on the tool bar.

3. In the browser, enter Keith in the first name entry, then

click Search. When the browser has displayed the list of

Page 6: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

6

people named Keith, click the Add all persons to contacts

link. Then click the Close my session link.

4. At this point, return to the Optimizeit Profiler and click the

Run garbage collector button. Look at the diffcolumn (you may want to sort by diff by clicking the headerof the diff column). You will see that some classes havecreated some instances since the last mark. The class withthe most instances is the String class. This means that someStrings have been created but not garbage collected. TheseStrings are therefore strong memory leak candidates. Thereis a possibility that these objects are actually cached or staticvariables of classes being loaded—we will see in the nextsection how to confirm whether they are leaks.

Finding out why the code is leakingWe now know which object class is leaking and are ready to

investigate why.

1. Select the String class, then click on the Show instances

and reference graphs in the Optimizeit Profiler

tool bar. The Optimizeit Profiler switches to the reference

view. This is the Optimizeit Profiler memory leak debugging

capability. The table on top is the Instance table. It shows

the list of all the instances of Strings and their values (if you

had selected a class other than the String class, you would

see the toString representation of the objects). The

instances are sorted by allocation date, with the most recent

on top.

2. Before going further, click the i button in the tool barto open the Inspector. Make sure you select the optionShow allocations since mark if it is not already selected.With this option selected, the Instance table shows only theinstances created since the last mark—that is, the potentialleaks.

3. Select a line showing java.lang.String Keith in theInstance table. The middle view is the Reduced ReferenceGraph view. It shows the reference graph for the selectedString, enabling you to understand why the object is notgarbage collected.

The Reduced Reference Graph should be similar to the

following image:

The graph shows the chain of references starting from the String

object. The word in bold at the beginning of each line is the

member variable of the object shown later on that same line, that

references the object from the previous line.

Working down from the String object, here is a detailed description

of what the graph shows:

• The String “Keith” is referenced by

• The firstName member variable of a Person object, whichis referenced by

• An array of Objects, which is referenced by

• The elementData member variable of a PersonList object,which is referenced by

• The addressBookListener member variable of theAddressBook1$ListenerElement object, which is referencedby

• An array of objects, which is referenced by

• The elementData member variable of a Vector object,which is referenced by

• The listeners member variable of an AddressBook1 object,which is referenced by

• The addressBook member variable of theAddressBookServlet object, which is referenced by

Page 7: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

7

• The servlet member variable of theorg.apache.tomcat.core.ServletWrapper object

• ...And finally by application server references.

When you add a person to your contact list, a Person object,

containing the information for that person, is created and added to

a list of people (PersonList object), which is added into the servlet

session context (so your contact list can be retrieved throughout

your session). When you close the session, the PersonList object is

removed from the session context.

This version of the AddressBook application is a prototype. The

final version is supposed to include mechanisms that would allow

administrators to add/remove/modify persons from the address

book. With that design in mind, a listener was added to the address

book, so that the PersonList objects are notified when the address

book changes. This allows a PersonList to be updated if it holds

information on a Person which has been modified. So that if you

add a person to your contact list, and while you are still using the

address book, some modifications are applied to the address book,

and your PersonList can be automatically updated, or you can

receive a warning that the address book has changed.

Looking at each line of the Reference Graph, we can see that the

String causing the memory leak is part of a Person object, which is

part of a PersonList referenced by the listener of the address book.

So the listener of the AddressBook object still holds a reference to

the PersonList. This prevents the PersonList—and all the objects it

holds—from being garbage collected. By removing the PersonList

from the AddressBook listener, we will allow the PersonList and all

the objects it holds (including all the leaking Strings) to be garbage

collected.

Pinpointing the line of code that is causingthe leakTo identify which line of code is causing the leak, let’s focus on the

bottom table of the window (the “Allocated at” table). This table is

the backtrace of the selected line in the Reference Graph. It allows

you to understand where the selected object has been created and

to identify the method calls leading to its creation. The first line in

the table shows the method and line of code responsible for the

allocation of the object. The second line is the method that called

the method of the first line. The third line is the method that called

the method of the second line, and so on. When you select a

different line in the Reference Graph, note that this table changes

to show the allocation backtrace for the selected object. Note also

that double-clicking any line in this table or in the reference graph

opens the source code viewer and highlights the relevant line

of code.

With the Reference Graph and the backtrace table, we can

understand exactly why the PersonList is referenced by the

AddressBook listener. A listener is a list of elements that references

the objects that should be notified. When you add an object to a

listener, it creates an element to reference that object to be notified

and add it to the listener list. So the creation of the listener element

is triggered because an object was added to the listener.

1. In the Reference Graph, select the line

addressBookListener of

AddressBook1$ListenerElement.... This represents the

ListenerElement.

2. Look at the backtrace table after double-clicking on the first

line AddressBook1.addListener(). The source code viewer

shows you where the ListenerElement is created. This is an

intermediate step in adding a listener, so we continue down

the backtrace to locate where the listener is added.

3. Click on the second line SearchServlet.service(). The

source code viewer now shows the following code (the

highlighted line is in bold):

Page 8: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

8

if (personList == null) { personList = new PersonList(); // Add a listener from the addressbook on that list, so the list can beupdated // if the address book changes

addressBook.addListener(personList);

session.setAttribute("personList",personList);}

This is the exact line of code that causes the PersonList object to

remain referenced by the AddressBook, thus creating the leak.

Correcting the code that is causing the leak From the code, we see that a PersonList is created, registered as a

listener of the AddressBook object, then put in the session context.

To fix the leak, the listener should be removed when the

PersonList is no longer needed. This should happen when the

session is closed in the AddressBookServlet.

Here is the AddresBookServlet.java code that closes the session:

// Here the user has chosen to closethe session // We only remove the significantvalues from the session if((closeSession!=null)&&(closeSession.equals("true"))) { sessionReset=true; session.removeValue("personList");

session.removeValue("personsFound"); addressBook.clean();}

The PersonList object had been removed from the session (and

stored as the attribute “personList”), but the program had

forgotten to remove the listener. The code is modified in the

AddressBookServlet2.java file, with the lines in bold fixing our

memory leak:

// Here the user has chosen to closethe session// We only remove the significantvalues from the sessionif((closeSession!=null)&&(closeSession.equals("true"))) { sessionReset=true; PersonList myContacts = (PersonList)session.getAttribute("personList"); if((myContacts!=null)&&(addressBook!=null))

addressBook.removeListener(myContacts);

session.removeValue("personList");

session.removeValue("personsFound"); addressBook.clean();}

Let’s test the new version of the application. Access the following

page in your browser http://localhost/addressbook2/enter. In the

Optimizeit Profiler, switch back to the Heap View by clicking the

Show Heap button on the tool bar. Run the garbage collector by

clicking the Run garbage collector button on the tool bar, then

put a mark (click on the button Mark current instance count). In

the browser, enter Keith in the first name entry, then click Start

search. When the browser displays the list of people found, click

the link Add all to my contacts then Close my session. Come back

in the Optimizeit Profiler and run the garbage collector again. The

number of objects in the diff column has decreased dramatically.

You will still notice a positive value in the diff column for the

String class. This is OK and does not mean you have a memory

leak. Because it was the first time the new AddressBookServlet2

was loaded, the constant Strings and static variables for that String

were created during this search.

.

Page 9: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

9

Conclusion: performance tuning iscrucial for Java™Conceiving, designing, and testing your approach against

performance goals as you build means more than just avoiding dog-

slow applications and crashes (though that’s always a good start).

By being appropriately alert to how your code performs

throughout the development process, you avoid expensive,

disruptive late-stage fixes. Fast, scalable, high-performance code is

a design imperative from the beginning. It is also a serious,

regularly exercised element of the development process for each

front-line developer (not a specialized skill for an isolated

performance team).

The premise behind getting tools like the Optimizeit Suite in the

hands of each developer on the team is simple: Nobody

understands a piece of code as well as the person who creates it,

and nobody is better positioned than the author to make

improvements in the logic and implementation of that code.

This Java performance tuning paper and test case has focused on

troubleshooting Java memory leaks. You have seen how to use the

Optimizeit Profiler to rapidly pinpoint and fix problems down to

the responsible line of code. While this J2EE Address Book

application example was small, it could be extended with EJBs that

perform the Address Book database transactions, or it could use

JMS, JNDI, or JDBC.® In each case, the Optimizeit Profiler would

provide you with all the necessary information to investigate

memory or performance issues across all EJBs, servlets, or JSPs.

Similar Borland® Optimizeit™ Suite guides are available, using the

same Address Book J2EE application example that describes how

to troubleshoot two other important Java performance problem

areas: speed bottlenecks due to poor CPU utilization and problems

caused by excessive tempory object allocations.

Borland® Optimizeit™ Suite tools makeperformance tuning easy

The 80:20 rule fits well for performance tuning. Eighty percent of

an application’s performance problems are usually caused by no

more than 20 percent of the code. The pitfall that development

teams fall into is that they delay the identification of key problem

areas until too late, leading to expensive and risky late-stage

application redesign. Taking a proactive approach will preempt just

this type of rushed, endgame rework. Adopting tools such as the

Optimizeit Suite allows everyone in a development team to

become more conscious of—and more conscientious about—the

application’s speed, scalability, and reliability throughout the

development process.

As each routine or subsystem’s basic functionality is established,

the module’s performance can be evaluated within the context of

the applications overall business requirements. Clearly not every

section of code will need to be labored over with equal intensity

(many parts will require no attention at all), and certain key issues

will emerge only as pieces of code are combined. Whatever the

situation, spotting and assessing the severity of issues throughout

the development process avoids delays, problem escalations, and

the kind of deep-rooted performance flaws that can sideline an

entire project or create business disasters once an application is live

wth customers in a production environment.

The Borland® Optimizeit™ Suite of performance tools let you keep

a tight rein on code, regularly testing where design and compiled

code meet hardware and Java virtual machine constraints. Your

efforts will stay focused on priority problems, and you will be

rewarded with fast, reliable, and truly scalable J2SE and J2EE

applications.

Page 10: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

10

Appendix A

Configuring the Optimizeit™ Profiler withyour application server

Integrating the Optimizeit™ Profiler with Tomcat 3.2.1The Optimizeit Profiler provides a wizard (accessible from the

Tools/Application server integration menu) which will

automatically perform the integration with Tomcat 3.2.1. Just run

the wizard, and it will guide you through the integration process.

Note that you can also use the tutorial available from the

Info/Tutorials menu. This tutorial describes how to manually

perform the integration.

Starting Tomcat for profilingOnce Tomcat has been integrated with the Optimizeit Profiler, use

the script tomcatWithOptimizeIt.bat to start Tomcat for

profiling. Once Tomcat has started, you can attach from the

Optimizeit Profiler GUI: start Optimizeit Profiler, then select the

Program/Attach menu. Keep 1470 for the Port Number value

then click Attach. You are now profiling in Tomcat.

JRun™ 3.0Integrating the Optimizeit Profiler with JRun™ 3.0

The Optimizeit Profiler provides a wizard (accessible from the

Tools/Application server integration menu) which will

automatically perform the integration with JRun 3.0. Just run the

wizard; it will guide you through the integration process.

Note that you can also use the tutorial available from the

Info/Tutorials menu. This tutorial describes how to manually

perform the integration.

Starting the profiling in JRun™ 3.0Once you have correctly configured JRun 3.0 for profiling with the

Optimizeit Profiler, restart the JRun server. From your browser,

access the Optimizeit Profiler servlet, with a URL similar to

http://localhost/servlet/OptimizeIt. Click on the Start

Optimizeit Audit System button on the servlet. The browser

should report that the Optimizeit Profiler Audit system is running

and waiting on port 1470. At that point, start the Optimizeit

Profiler, if it is not already started, then select the

Program/Attach menu. Keep 1470 for the Port Number value

then click Attach. You are now profiling in JRun.

Integrating the Optimizeit™ Profilerwith BEA® WebLogic® 5.1The Optimizeit Profiler provides a wizard (accessible from the

Tools/Application server integration menu) which will

automatically perform the integration with WebLogic 5.1. Just run

the wizard; it will guide you through the integration process.

Note that you can also use the tutorial available from the

Info/Tutorials menu. This tutorial describes how to manually

perform the integration.

You will have to modify the script used to start WebLogic to add

the Xerces(XML) jar file to the CLASSPATH. This is described in

the Appendix B: Deploying in WebLogic 5.1.

Starting WebLogic® 5.1 for profilingOnce WebLogic has been integrated with the Optimizeit Profiler,

use the script startWebLogicWithOptimizeIt.bat to

start WebLogic for profiling. Once WebLogic has started, you can

attach from the Optimizeit Profiler GUI: start Optimizeit

Profiler, then select the Program/Attach menu. Keep 1470 for

the fcPort Number value then click Attach. You are now profiling

in WebLogic.

Page 11: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

11

Other application servers

Configuring the Optimizeit™ Profiler with other J2EE™

application serversMany current application servers are fully J2EE compliant and so

support the deployment of Web Archive (WAR files). The

Optimizeit Suite works with and supports most of the major

application servers. Please consult the documentation of your

application server and contact us at www.borland.com/optimizeit

for a complete list of application servers or for other information.

Appendix B

Deploying the Address Book J2EE™

application example in your applicationserver

Deploying in Tomcat 3.2.11. Copy the files addressbook.war, addressbook1.war,

addressbook2.war and addressbook3.war under the

directory <Tomcat>\webapps (where <Tomcat> is the

directory where you installed Tomcat).

2. Restart the Tomcat server.

The different versions of the Address Book J2EE application

example can be accessed with URLs similar to:

http://localhost/addressbook/enterhttp://localhost/addressbook1/enterhttp://localhost/addressbook2/enterhttp://localhost/addressbook3/enter

Note: You may have to modify these URLs if your application

server does not use the port 80. If it uses the port 8080, for

example, the URLs become:

http://localhost:8080/addressbook/enter

Deploying in JRun™ 3.0You will need the version 3.02 or later of JRun to deploy the

Address Book Test Case. Make sure to update JRun to that version

or later if you run a version prior to 3.02.

1. Access the JRun Management Console from your browser.

If you have a default install, the URL http://localhost:8000

will take you there.

2. Login.

3. On the left side of the browser, click on the server where

you would like the address book to be deployed.

4. On the right side of the browser, click on the link [ WAR

deployment ]

5. In the Servlet WAR File or Directory field enter the path

to the addressbook.war file (you may use the Browse button

to browse for this file).

6. In the JRun Server Name list box, make sure to select the

server where the Address Book J2EE application example

should be deployed.

7. In the Application Name field, enter AddressBook

8. In the Application URL field, enter /addressbook

9. Click the deploy button. After a few seconds, JRun should

report that the war file has been successfully deployed.

10. Perform Steps 5 to 9 again with the war files:

addressbook1.war, addressbook2.war, and

addressbook3.war. Use the respective Application Names

AddressBook1, AddressBook2, and AddressBook3; and use

the Application URLs /addressbook1, /addressbook2

and /addressbook3.

11. After successfully deploying the four war files, restart the

server. To do this, click the node of the server where you

Page 12: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

12

have just deployed on the left side of the browser, then click

the restart server button on the right side of the browser.

The different versions of the Address Book J2EE application

example can be accessed with URLs similar to:

http://localhost/addressbook/enterhttp://localhost/addressbook1/enterhttp://localhost/addressbook2/enterhttp://localhost/addressbook3/enter

Note: You may have to modify these URLs if your application

server does not use the port 80. If it uses the port 8080, for

example, the URLs become:

http://localhost:8080/addressbook/enter

Deploying in WebLogic® 5.11. Create a directory where the first version of the

addressbook will be stored (you can choose any directory,

for example c:\weblogic51\example\addressbook).

2. From the command line, go into this directory and unjar the

addressbook.war, using the command line:

jar xvf addressbook.war

Note: You need to have jar in your PATH to be able to run

this command line. If jar is not found, make sure to add

<JDK>\bin in your PATH, where JDK is the directory

where you installed your JDK.

3. Repeat the previous steps with the files addressbook1.war,

addressbook2.war, and addressbook3.war (for example,

extract these files in directories:

c:\weblogic51\example\addressbook1,

c:\weblogic51\example\addressbook2,

c:\weblogic51\example\addressbook3)

4. Edit the weblogic.properties file (this file should be located

under your WebLogic directory). Append at the end of the

file the following lines:

weblogic.httpd.webApp.addressbook=c:/weblogic51/examples/addressbook

weblogic.httpd.webApp.addressbook1=c:/weblogic51/example/addressbook1

weblogic.httpd.webApp.addressbook2=c:/weblogic51/example/addressbook2

weblogic.httpd.webApp.addressbook3=c:/weblogic51/example/addressbook3

Make sure to use / instead of \ in the paths.

You also need to have the Xerces (XML) package added in your

classpath:

1. Download Xerces if you do not have it from

http://xml.apache.org/dist/xerces- j/Xerces-J-bin.1.3.1.zip

2. Unzip the Xerces-J-bin.1.3.1.zip package on your disk

Edit the file startWebLogicWithOptimizeIt.bat and add the

path to the xerces.jar file contained in the package you have

just extracted after the line starting with:

set JAVACLASSPATH=

3. Restart the WebLogic server with the script

startWebLogicWithOptimizeIt.bat. The different versions

of the Address Book J2EE application example can be

accessed with URLs similar to:

http://localhost/addressbook/enterhttp://localhost/addressbook1/enterhttp://localhost/addressbook2/enterhttp://localhost/addressbook3/enter

Page 13: Performance Tuning Essentials for Java and J2EEedn.embarcadero.com/article/images/28757/java_memory_leaks.pdf · Performance Tuning Essentials for J2SE ™ and J2EE ™ Minimize memory

Optimizeit™ Suite

13

Note: You may have to modify these URLs if your application

server does not use the port 80. If it uses the port 8080, for

example, the URLs become:

http://localhost:8080/addressbook/enter

Appendix C

Troubleshooting

My application server is not described in this document, how

should I proceed?

Most of today’s application servers are fully J2EE compliant and

will therefore support the deployment of Web Archive (WAR

files). Please consult the documentation of your application server.

With JRun 3.0, the browser displays a Null Pointer Exception

caused by a Servlet Exception when I access the Address

Book page.

You may be running a version of JRun prior to the 3.02 (JRun 3

Service Pack 2). The version of JRun you are running can be

checked from the default page of the JRun Management Console.

Make sure to upgrade your JRun server to the 3.02 version of JRun

or later.

With WebLogic 5.1, the Browser displays “Error 500 Internal

Server Error” when I access the Address Book page.

Look at the console where you started WebLogic. If you get the

exception java.lang.NoClassDefFoundError:

javax/xml/parsers/ParserConfigurationException it means

the CLASSPATH is not set correctly and does not include the

xerces.jar file. Make sure to double check the CLASSPATH in the

script that you use to start WebLogic.

My question is not addressed in this document, what should I

do next?

Send any question you may have to the Optimizeit technical

support team at www.borland.com/optimizeit . Please make sure

to describe the issue precisely, including your platform, your

application server, and any error message and stack trace generated

Made in Borland® Copyright © 2002 Borland Software Corporation. All rights reserved. AllBorland brand and product names are trademarks or registered trademarks of Borland SoftwareCorporation in the United States and other countries. Java and all Java-based marks aretrademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. Allother marks are the property of their respective owners. Corporate Headquarters: 100 EnterpriseWay, Scotts Valley, CA 95066-3249 • 831-431-1000 • www.borland.com • Offices in: Australia,Brazil, Canada, China, Czech Republic, France, Germany, Hong Kong, Hungary, Ireland, Japan,Korea, the Netherlands, New Zealand, Russia, Singapore, Spain, Sweden, Taiwan, the UnitedKingdom, and the United States. • 12957

100 Enterprise WayScotts Valley, CA 95066-3249www.borland.com | 831-431-1000


Recommended