Java Performance Tuning

Java(TM) - see bottom of page

|home |services |training |newsletter |tuning tips |tool reports |articles |resources |about us |site map |contact us |
Tools: | GC log analysers| Multi-tenancy tools| Books| SizeOf| Thread analysers| Heap dump analysers|

Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks! 

Training online: Concurrency, Threading, GC, Advanced Java and more ... 

The Roundup August 2003

Get rid of your performance problems and memory leaks!

Modern Garbage Collection Tuning
Shows tuning flow chart for GC tuning

Java Performance Training Courses
COURSES AVAILABLE NOW. We can provide training courses to handle all your Java performance needs

Java Performance Tuning, 2nd ed
The classic and most comprehensive book on tuning Java

Java Performance Tuning Newsletter
Your source of Java performance news. Subscribe now!
Enter email:

Training online
Threading Essentials course

Get rid of your performance problems and memory leaks!

Back to newsletter 033 contents

What's in a Performance Tip

Every month, Jack has been posting about 100 performance-tuning tips that he extracts out of performance tuning articles and other sources on the net. Even at that rate, it has been impossible for Jack to keep pace with the number of tips that are being generated from all of the available sources. Even though we do a cursory vetting of the tips that we post, that still leaves a large number of tips that one can only hope have some validity? For example, I recently read an article that was published at Developer-Works. Given the difficulty to get an article through the editorial process before DW will publish it, I was quite surprised to find that I could not reproduce the results stated in the article. Does this mean that those results are invalid? Because none of the conditions under which the tests were run, nor was the source code published, it's a question that I can't answer.

Producing a micro-performance benchmark that you can trust is difficult. The reason why it is so difficult is because of the JIT optimizing compilers. If the optimizing compiler determines that it can throw away a set of instructions, it will! It might take 2 or 3 recompiles but, that code will disappear. Now, if the effect that you are trying to measure is embodied in code that the optimizing compiler thinks it can dispose of, you wouldn't be able to measure the effect. Worse yet, if the optimizing compiler decides to do it's magic in the middle of your benchmark, then again, your results will be invalid. Now this in itself is not too big of a problem -- as long as you know about it. And here-in lies the problem, the optimizing compiler is just going to quietly to wht it does, and you are not going to know about it.

About the best you can do is use statistics and common sense to determine if your benchmark has run without any interference. The key numbers to consider are, the minimum run time, the average run time, and the 95th percentile run time (one tailed probability distribution function). If all of these numbers are "close" to each other, then you can be sure that the minimum runtime is the value that you are looking for -- unless the instructions have been optimized completely out of the test run. And now for performance tips that you can count on.

The JavaRanch

In one of the most interesting posts that I've seen in any of the performance discussion groups, a the bartender at the Java Ranch offered the best explanation that I've seen to date on how a Java program could run faster than it's C/C++ equivalent. First, the optimizing compiler compiles byte code down to native assembler. Ok, no big deal here, so do the C/C++ compilers and if that were the end of the story... The interesting part comes with the realization that the native code produced by the optimizing compiler will have undergone optimizations based on the current runtime conditions, something that the C/C++ static compliers are incapable of doing. Thus, the native code that is produced by the JIT may actually be more highly optimized for the task it is performing. To complete the story, a greenhorn stepped in an noted that when he used JRockit Windows (BEA's VM optimized for server performance), he was able to measure an 28% increase in performance over the highly optimized C version of the benchmark.

In another post, we see a good example of where software metrics plays a role in the decision making process. In this post, a greenhorn has a piece of code that he needs to performance tune. Problem is, the code has an extremely high McCabe Complexity number. Now, McCabe Complexity is a measure of the number of paths that one can take though the code (a count of branch statements). The higher the number, the more complex the code is, the lower level of abstraction that can be found in the code. These characteristics often lead to code that is more error prone and much more difficult to refactor, which is of course what the greenhorn wanted to do. Now, having a high complexity measurement should not scare you off of refactoring but, it should be a warning that you are about to embark on a journey that will most likely be as difficult as it is unpredictable.

The Server Side

From the server side, we come across a discussion that questions the usefulness of using an external over an internal cache. The discussion wandered through the various issues of GC, IPC [inter-process communication], memory footprint until it finally clicked. The overhead of serialization and de-serialization would render the technique [external caching] ineffective. The participants concluded that it would be much better to just add RAM to the system. This point becomes even more powerful when you start to consider the improvements to GC in the JDK 1.4.

In another post on the serverside, the question of whether to use a second VM or increase the allocation of threads and heap in a single VM. As with any performance questions, the solution often involves a trade-off. In this instance, the trade-off is having all of the data in a single VM or having it spread out between the two. The next trade-off is the effects on GC. Running GC over a smaller space will result in fewer application pauses and ease the burden on the thread scheduler. So, with this in mind, we must look to the application to see if it can point us to one direction or the other.

This application is running in Weblogic 6.1, which pins us down to the JDK 1.3. Details about the application indicate that it's stateless. This is great news as it makes the recommended solution to use two VMs easy to implement in this case. But one other point, most performance tuning tips do have a shelf-life and this tip is no different. Improvements in heap and thread management in the JDK 1.4 might be enough to reverse the advice to run the application in a single VM. Certainly if the improvements in the JDK 1.5 prove to be just a significant, these types of performance tuning techniques will become less prevalent.

This month, we feature the re-emergence of Java Gamming. As was reported a couple of months ago, Java Gaming was moved to the new site. We at Java Performance are quite happy to see that the community has successfully moved and has retained its character and fervor.

Not really to do with performance but, an interesting thread was started with someone asking the question: is doing this (referring to the code snippet below where an object lock is reassigned during a synchronized block) a bad idea?

SomeObject myObject;
syncronized(myObject) {
  if(somecondition) myObject = new SomeObject();
  ...more stuff..

Clearly, there is a problem with this code as myObject has not been initialized and consequently, the synchronized statement will fail. But, lets just say that myObject has been properly initialized, what then? The answer is nothing. Not that this seems like something that you should be doing but, there will be no side effects on synchronization if you do. This is because the synchronized statement forces the thread to grab the monitor for the object, and myObject is a reference. Now, you will not be able to send a notify message to myObject after the assignment. If you do send a message notify message to myObject, you will cause the application to throw an exception because, you don't own the monitor of the object being referenced.

Ever see a claim stating that an obfuscating tool can actually have a positive impact on performance? Well, it used to be true and it most likely is true to a certain extent. The trouble is, it used to be true back in the days when most people were still developing with the JDK 1.1. Now with JIT/optimizing compilers built right into the VM, the performance is less effected by long method names, many methods and a whole host of other issues that can interfere with an applications performance. Best bet, get an evaluation license and check it out for yourself before investing in the technology.


Finally, Jack and I have been experimenting with the new JRockit release. This VM, based on the JDK 1.4 specification, contains a really interesting monitoring feature. If you turn on monitoring but don't attach a client, the monitoring adds no overhead to the cost of operating the VM. If you do attach a monitoring client, you'll find that the monitoring creates less than a 5% drag on performance, maybe as low as 1%. It's not often that I will plug a product in this column but, this is certainly one technology that is worth investigating.

Kirk Pepperdine.

Back to newsletter 033 contents

Last Updated: 2023-09-28
Copyright © 2000-2023 All Rights Reserved.
All trademarks and registered trademarks appearing on are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
RSS Feed:
Trouble with this page? Please contact us