Building and Deploying Reliable High-Performance Java Applications
Building and Deploying Reliable High-Performance Java Applications
Along with the productivity and technology advancements gained Java performance and reliability
with J2EE come complexity and some unique development
Apart from design-specific logic errors and implementation errors,
challenges, including optimizing code performance, efficient
most software problems can be categorized as performance or
utilization of memory, proper management of threads and effective
reliability issues. Java performance and reliability problems can
testing. This paper will address those challenges and provide a
occur for many reasons, often due to:
solution framework for overcoming them.
Inefficient application codePerformance
Java software development challenges Slow code is a problem in any application. Slow Java code can be
a more difficult problem due to the complexity of the runtime
As a language, object model and runtime environment, Java
environment. Java code can run differently from environment to
technology is extremely powerfulbut not a panacea. Multi-tier
environment. Parts of your Java code may be JIT compiled by one
Java applications can be complex, using a combination of
virtual machine, but interpreted by another. In some cases, your
technologies such as Web services, Java servlets, JavaServer Pages
application may be quite efficient, but may use runtime classes
(JSP), Enterprise JavaBeans (EJB), application servers, web servers,
from the Java SDK that introduce performance bottlenecks to your
servlet engines and standalone Java runtime environments.
application. The Java virtual machine and its method calls into
the underlying operating system can also cause avoidable
performance bottlenecks.
To solve problems with inefficient application code, Java 3. How many allocations are made by each function and each line
developers should understand the answers to questions like these: of code?
1. What are the most expensive methods in my code? 4. Can I modify my allocation-intensive code to allocate once and
re-use memory for the lifetime of the method?
2. Which lines of code in these methods are being executed
most frequently, and which lines of code are using the most 5. Are there large blocks of memory being allocated early in
CPU time? execution that could be delayed or eliminated altogether?
3. Can I modify the slowest lines of code for an incremental 6. Can I avoid using certain Java runtime components that make
improvement in runtime performance? inefficient use of memory?
4. Where are the performance bottlenecks in the Java runtime Improper thread managementPerformance + Reliability
classes, virtual machine and operating system? By nature, Java is a multi-thread, event-driven environment.
Efficient synchronization and use of threads can dramatically
5. Can I modify my code to avoid using these expensive classes
increase performance and scalability, particularly with server code.
and methods in favor of a solution that will result in faster
Conversely, poor synchronization techniques and inefficient use of
runtime performance?
threads can degrade performance and cause problems with reliability
Poor memory utilizationPerformance + Reliability and scalability. Much like memory utilization problems, thread
Java was intended to be an environment free of memory errors problems in a server-side application that services many users
associated with programmer-managed memory, which are common simultaneously can seriously degrade server-side application
in C and C++. While a significant number of problems were performance and reliability.
eliminated, other types of memory problems became part of the Java
Improper thread management techniques can result in performance
environment. Dealing with Java memory problems requires a new
problems due to thread starvation or thrashingconditions that can
approach to analyzing a programs use of memory.
be easily addressed if the cause can be identified. Other thread
Java developers have a good amount of control over efficient problems can seriously affect application reliability, such as deadlock,
memory allocation and utilization. Calls to allocate memory in unsynchronized access to data and thread resource leaks. These
a Java program are very expensive, and can cause noticeable problems can be time-consuming to resolve without the proper tools.
performance degradation. Inefficient use of allocated memory Thread problems should be suspected and thread behavior analyzed
can compound this effect, causing serious reliability problems. when a sporadic runtime problem occurs that has no apparent cause,
or when performance problems persist even after code has been
Consider a server-side Java application that services tens of
tuned for optimal performance and memory utilization. In such
thousands of users simultaneously. If a Java component misuses
cases, Java developers should consider questions like these:
100KB of memory for each user instance, it can easily consume
server resources as load increases, wasting 1GB of memory for every 1. Does most of the application run acceptably, while certain parts
10,000 users. As server resources are depleted, other applications run sluggishly? [possible thread starvation]
will become unstable and could completely cut off application
2. Is the entire application inexplicably slow? [possible thrashing
availability. This is obviously an undesirable situation for any
condition]
e-commerce application.
3. Can I adjust the priority level of my program threads to allow
Before a Java application is deployed, its memory utilization should
sluggish threads to get more relative CPU time, or to reduce the
be carefully examined and optimized. Java developers should
overhead associated with excessive context switching? [possible
consider questions like these:
cause]
1. Which methods in my code are allocating the most memory?
4. Does my program run normally, but occasionally hang for
2. Which lines in these methods are responsible for allocating the no apparent reason? [possible timing-related deadlock]
most memory?
2
5. Does my program experience corruption of data that is accessed compiled code, third-party components, JavaServer Pages, Enterprise
by multiple threads? [possible unsynchronized access to data] Java Beans and Web services, as well as the virtual machine and
underlying system code. When comparing the DevPartner
6. Does my multi-threaded programs runtime behavior conform
performance profiler to other Java profiling tools, an important
to its intended design? [possible cause]
point to consider is the value of complete top-to-bottom visibility.
Incomplete testingReliability
The DevPartner performance profiler accurately measures time spent
Determining how well an application has been tested can be
in virtual machine methods and in OS methods separately from
somewhat subjective, leading to the uncertainty most developers and
time spent in Java application code. This makes it a fast and easy-to-
development managers experience at milestones such as code check-
use tool that can accurately identify the most expensive performance
in, unit testing, or integration testing and final release. At each
bottlenecks.
milestone, Java developers should ask:
Memory profiling
1. How much of the application code was actually tested or, even
DevPartner Java Edition includes a memory profiler that
more important, how much code was NOT tested?
automatically locates memory-intensive methods in Java code. With
2. Are the current test suites adequate for exercising all of an accurate profile of a Java programs memory usage, developers can
the application code? Did the entire test suite execute prior improve the runtime performance and resource utilization of their
to deployment? code by optimizing methods that consume or waste the most
memory. The memory profiler saves valuable development time
3. How stable is the code base?
by helping developers quickly locate inefficient code that would
4. What percentage of the code base was modified just prior otherwise take hours or days to find manually.
to release?
The DevPartner memory profiler is fast, easy to use and does NOT
5. Were test suites revised to exercise the most recent require any code re-compiling. In traditional Sun Java environments
code changes? it uses a very fast, lightweight instrumentation technique combined
with the standard Java Virtual Machine Profiler Interface to collect
Solving Java performance and reliability problems memory-usage statistics with the minimum amount of intrusion.
3
CompuwareCorporation
All Compuware products and services listed within are trademarks or registered trademarks
of Compuware Corporation. Java and all Java-based marks are trademarks or registered
trademarks of Sun Microsystems, Inc. in the United States and other countries.
All other company or product names are trademarks of their respective owners. 10/04
2004 Compuware Corporation