BUGS AND PERFORMANCE ISSUES AREN'T LIMITED TO THE JVM
The performance of the database is the example used in this section, but any part of the environ-
ment may be the source of a performance issue.
I once faced an issue where a customer was installing a new version of an application server, and
testing showed that the requests sent to the server took longer and longer over time. Applying Oc-
cam's Razor (see the next tip) led me to consider all aspects of the application server that might
be causing the issue.
After those were ruled out, the performance issue remained, and there was no backend database
on which to place the blame. The next most likely issue, therefore, was the test harness, and some
profiling determined that the load generator—Apache JMeter—was the source of the regression:
it was keeping every response in a list, and when a new response came in, it processed the entire
list in order to calculate the 90th% response time (if that term is unfamiliar, see Chapter 2 ).
Performance issues can be caused by any part of the entire system where an application is de-
ployed. Common case analysis says to consider the newest part of the system first (which is often
the application in the JVM), but be prepared to look at every possible component of the environ-
On the other hand, don't overlook that initial analysis. If the database is the bottleneck (and
here's a hint: it is), then tuning the Java application accessing the database won't help overall
performance at all. In fact, it might be counterproductive. As a general rule, when load is in-
creased into a system that is overburdened, performance of that system gets worse. If
something is changed in the Java application that makes it more efficient—which only in-
creases the load on an already-overloaded database—overall performance may actually go
down. The danger there is then reaching the incorrect conclusion that the particular JVM im-
provement shouldn't be used.
This principle—that increasing load to a component in a system that is performing badly will
make the entire system slower—isn't confined to a database. It applies when load is added to
an application server that is CPU-bound, or if more threads start accessing a lock that already
has threads waiting for it, or any of a number of other scenarios. An extreme example of this
that involves only the JVM is shown in Chapter 9 .