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|

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

Training online: Threading Essentials course 

Newsletter no. 31, June 25th, 2003

JProfiler
Get rid of your performance problems and memory leaks!


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


JProfiler
Get rid of your performance problems and memory leaks!


We are branching out from our successful on-site training courses to provide public courses. From current demand, our first course is likely to be in London, UK. If you are interested in Java performance training in London, please contact us.

1.5 seems to be nearly a year away? So I hear. And 1.6 is likely to be three years away. So if you want to get any features voted in to 1.5 you'd better do it now. Misha Dimitriev, the author of the JFluid technology I mentioned last month, wants your help to get JFluid technology voted in to 1.5. In case you forgot, this is a Sun project, and the technology would enable standard HotSpot JVMs to be dynamically attached to at any time for profiling. No slowdown when not attached, but profiling possible at any time. That looks pretty good to me. Go and vote (needs account, registration is free, it may take a couple of days before the bug appears in the database).

We are trying to move to a more weekly publishing mode. The newsletter will still only be emailed once a month, but individual columns will become available earlier, on a weekly basis. Plus we should have some new tips every week. You can track this by visting the home page or the newsletter page if you like to get your updates more frequently than once a month.

A note from this newsletter's sponsor

Get a free download of GemStone Facets 2.0 and see how this
patented technology supports JCA 1.0 to seamlessly integrate
with J2EE application servers to enhance performance.

This year, I've decided to extract the tips from the JavaOne presentations. I don't normally, because despite the 20-30 or so performance related presentations available each year, the target is broad based education; the presentations rarely have anything new to say about performance in the way of new tips, i.e tips that are not already detailed here at JavaPerformanceTuning.com.

And despite this year being the same, I felt that the interest surrounding Java's premier annual event justified spending the time on the JavaOne presentations. Certainly they are interesting, especially the architecture case studies. It is good to see that Java is the basis behind so many really big enterprise sites (EBay, CapitalOne, WSJ.com, more). So check the presentations I've covered, and with our new weekly format, I'll cover more in the coming weeks.

We also present our regular features this month. Kirk's roundup covers garbage collection, store checkouts, stateless beans, and much more including a really curious synchronization code snippet. This month's interview is with Philip Aston and Peter Zadrozny of BEA Systems. Our question of the month is about using import statements;

Javva The Hutt is on holiday, but of course we have nearly 100 new performance tips extracted in concise form.
(Note: Backlogged articles still growing.)

A note from this newsletter's sponsor

Java/J2EE performance or scalability problems? Do NOT buy additional
hardware, do NOT buy additional software, do NOT refactor your app.
JTuneTM GUARANTEES improvements with none of the above costs.

News

Java performance tuning related news.

A note from this newsletter's sponsor

Quest Central for J2EE is an integrated application performance management solution that enables a diverse team of experts to detect, diagnose and resolve critical J2EE performance issues faster.

Tools

Recent Articles: JavaOne presentations

Jack Shirazi


The Roundup

Have you ever been to Kroger's? Given the diverse distribution of this newsletter, my guess is that most of you have not even heard of Kroger's. I had never been to Kroger's until late one night I needed a few groceries. Kroger's is large grocery store chain that is open 24 hours a day. What is interesting about this change is that they have an automated checkout system, which allows you to calculate the bill and pay for it with little if any human intervention. Here is how it works.

The automated checkout system is limited to express checkout rules. In other words, one can checkout 15 or fewer items. The automated checkouts are traditionally situated in the front of the store. Each point-of-sale contains four kiosks, which are monitored by a single employee. Customers walk up to the kiosk and start the checkout process by scanning those items that have bar codes. Once an item is scanned, you are required to set it in a bag that is sitting on end of the kiosk. Once an item is placed in the bag, it cannot be removed without causing the process to be halted and employee intervention to continue. Items, such as vegetables, that do not have bar codes are identified and priced by the employee. A camera system is installed at each kiosk so that the employee can perform this task from a centralized location. Once all of the items have been accounted for, you then proceed to pay either using cash or a bankcard.

The do-it-yourself checkout experience is much slower than having a store clerk do the work. But, with four stations, you do spend less time queuing, which makes up for the slower checkout time. So, you don't get 4-times throughput on the system but it is better than 1-time. And given that checkout is both a psychological and labor cost center, improving overall service time can make a difference in the efficiency of the overall system. Now lets look at some Java Performance tips.

The JavaRanch

Our journey begins at the Java Ranch where we find the ranch hands have taken over the conversation for a change. The first question asked about the downsides to calling System.gc(). The only downside reported is that the call may not do anything. The specification only guarantees that GC will be run before the VM throws an OutOfMemoryError. From a more pragmatic point of view, I've never seen Sun's VM ignore a request to perform a GC. And as the bartender pointed out, if you know that your application is going to pause and you know that the heap contains a lot of dead objects, then it makes sense to make a call to System.gc().

I'd go further, if you know you have a natural pause in the application, why not make the call. Doing this may simulate incremental GC which may, or may not actually save you pause time in the near future. On the other hand, where there are no natural pauses, I know that calling System.gc() can slow down the system by forcing the garbage collector to run when it would not need to. This is sufficiently performance draining that the latest JVMs have a flag which, when set, tells the JVM to completely ignore calls to System.gc().

Once the dust had settled on the question of garbage collection, a greenhorn walked in and started up on stateless session beans. He had a whole wagon full of questions about session pooling, how many clients can a session bean service, and what happens if the application crashes when it has 1000s of clients executing methods. The bartender quickly quieted the green horn down with a shot of wisdom. First, the J2EE specification does not require an application server to implement session bean pooling. In fact, I've heard rumors that some vendors have not even bothered to do anything else except setup a 1 to 1 client to stateless session bean ratio.

But, having said this, better not store intra-call state in the bean as the spec deliberately prohibits this activity. If pooling is in place then you can expect that the average number of beans that you'll need is the average service time multiplied by the frequency with which calls are made. And of course, these values could change for each every service offered by every stateless session bean. Problem is, this only defines an average. Actual values may vary greatly leaving some clients out in the cold for a very long time unless the pool is allowed to grow in size. All in all, it's not a subject for greenhorns to get lassoed into.

Just to prove that it is not only the greenhorns that have troubles, a ranch hand walked into the saloon after encountering an OutOfMemoryError. He was trying to parse two 45-megabyte XML files. Now it's not clear if he was using a SAX or DOM parser, but it was suggested by the bartender that a 45-Megabyte XML file could produce upwards of 400 Megabytes of garbage. Now, that is a lot of shoveling for anyone to take on let alone a poor VM with not enough memory to handle the task. Anyway, the issue is that the default VM settings will not tolerate this type of memory consumption. They can be set using -Xmx option. In this instance, it may make sense to go one step further and set the -Xms option to the same value so that the heap is fixed in size and time is not wasted resizing it. So, with this problem solved, lets trip over to the server side to see what the city slickers are up to.

The Server Side

The first question up for discussion is; is the JDO faster than the JDBC? On the surface, it sounds like we have two potentially competing technologies but, that myth is dispelled as a post quite correctly points out that the JDO is a higher level of abstraction that depends upon the JDBC. Since the JDO is layered on top, it cannot be faster. So, why would one use a technology that cannot be faster? In this case the answer is that it is much faster to develop object relational mappings using the JDO. As long as performance is adequate, good design wins over good performance.

Have you been missing submissions from ECPerf? Well, rest assured, you are not alone. It's not that ECPerf is no longer being used. In fact, I know of at least one organization that is relying on it. So, where has it gone? Well, it is now a Spec project. But, don't expect the frenzy of announcements that we once saw. An ECPerf benchmarking exercise is expensive to conduct. Consequently, only the big boys can afford them. The new name is SPECjAppServer200x.

Finally, we have a question regarding object relational mappings. The poster is looking for a load-on-demand feature. The response was overwhelming to use TopLink. I've worked with TopLink so, I have a little bias for the tool. In addition, if you recall our interview with Mike Norman, then you know that Oracle is positioning this product for performance. When asked about performance, the answer in the past has been, "how fast is your bicycle?" As cute as the answer is, TopLink and other O/R mapping tools do cost but, considering that 30-40% of an application team's time maybe working on solving that problem, the price tag of 7000USD/CPU can be recouped fairly quickly. If you use the Oracle 9i application server stack, then it's included which makes the ROI even shorter.

JavaGaming.org

For the last time, we move on to review the happenings in at www.javagaming.com. The site has been moved to www.java.net and it would seem that the discussion groups have been discontinued whilst the administrators move house. With that, we start with a post regarding synchronization. The question is, is this a bad idea:

SomeObject someObject ;
//
synchronized( someObject) {
   doSomeStuff();
   if ( someCondition) someObject = new SomeObject();
   doSomeOtherStuff();
}

In short, the answer is, this is no way to protect a critical block. For starters, synchronization relies on a thread acquiring a monitor in an object, not the reference to the object. So, when someCondition is met and the object reference someObject is altered, that leaves the block vulnerable to another thread to enter at the same time. Fortunately, assignment is an atomic operation and as such, will not leave the VM in the situation where someObject is null and hence cause an internal failure in the VM.

If there is one thing in particular that game programmers want, it's an accurate timer. The gaming experience depends upon it. Without it, the game will not flip through frames at a constant rate of speed. This will give the users a jittery experience. So, it was not surprising when the topic of timers came up again.

The question is, will System.currentTimeMillis() start falling behind if the computer is under heavy load? It turns out, there are two gotchas. The first is that different systems have different clock resolutions. For instance, the W2K laptop that I'm currently using provides me with a 10ms timer resolution. My Solaris box provides me with a 1ms timer resolution. Other systems may only provide a 25ms timer resolution. Given the wide variation, what is a game programmer to do? The choices are, skip some frames or lower the quality when you are behind. You maybe surprised to hear that lowering a precision threshold is a common solution used not only in the gaming community. For statistical processes, it may not matter if your calculation is not perfect once you've considered the amount of error that may exist in the data. The point is that as programmers, we are taught to be precise and in most instances, this is good advice. But, there are certain instances when large gains can be made with a calculation that is less than precise with no loss of value.

Oh yeah, the second gotcha is that Thread.sleep() only changes the state of a thread to runnable once the sleep time has run out. This in no way means that the thread will run at that instant.

With this, we sign off on www.javagaming.org as we anxiously await the startup of the java.net site. Your efforts have been put to good use by Sun in it's new NIO package as well as some of the newer settings on the VM. To all of those gamers that have been an inspiration to this column I can only say thank you.

Kirk Pepperdine.


Javva The Hutt

Javva The Hutt is on holiday this month

BCNU

Javva The Hutt.


The Interview: Philip Aston and Peter Zadrozny of BEA Systems

This month we interviewed Philip Aston and Peter Zadrozny of BEA Systems. For those of you interested in a little trivia, Peter takes our record for having the shortest email address we've seen to date: 9 characters for the whole address including '@' sign and domain name.

JPT: Can you tell us a bit about yourself and what you do?

Peter: I'm the Chief Technologist for Europe, Middle East & Africa for BEA Systems. If we go beyond the fancy title, what I really do is help BEA customers to be successful. I do this by assisting them in resolving issues at the moment of design and architecture of solutions all the way through to deployment and performance issues. Additionally I speak at conferences and seminars.

I have written a couple of books, starting with the first ever book on WebLogic Server. The second book was "J2EE Performance Testing", where Phil and Ted Osborne helped me out. I also started the WebLogic Developer's Journal, from idea to the first three issues.

Phil: I'm a consultant for BEA Professional Services in the UK. I spend my working life helping customers to use BEA products, in particular WebLogic Server.

In addition to co-authoring "J2EE Performance Testing", I write occasionally for the WLDJ and BEA's dev2dev site.

Of particular interest to readers of JavaPerformanceTuning.com, I am the author of The Grinder, a Java load testing framework (http://grinder.sourceforge.net/).

JPT: What do you consider to be the biggest Java performance issue currently?

Phil: A couple of years ago I might have picked on the ability of JVMs to make efficient use of multiple CPUs or moaned about stop-the-world garbage collectors, but today its hard to find anything that stands out as a Java specific problem.

Peter: Sure, gone are the days of JDK 1.0. With the work that the JRockit team is doing on adaptive and dynamic techniques with their JVM, and the research they are doing for future versions, I'm convinced that performance is not really a Java issue.

Phil: Thinking further, there are a couple of secondary issues that spring to mind. It will be a while before the JDK 141 NIO facilities is in common use and Java can be as efficient as native code for shifting bytes. Secondly, there is a class of applications (for example aspect oriented programming) that make extensive use of reflection; improvements to the run time performance of introspection would be welcome here.

Of course, the biggest performance issues are down to architects attempting to achieve the impossible. I'm happy to say that there are no longer any problems caused from having chosen Java as their tool.

JPT: Do you know of any requirements that potentially affect performance significantly enough that you find yourself altering designs to handle them?

Phil: Peter and I obviously have a J2EE perspective and the problems we encounter are server side. Nine times out of ten, the big issues here are around how to efficiently manage state while keeping within the requirements for integrity, currency, and availability. EJB CMP engines have matured slowly but surely, so that they are an appropriate answer to many of these problems. Your readers may be interested in the relatively new optimistic concurrency strategy for WebLogic Server that makes it easy to create a write-through application tier cache with transactional integrity. See my paper on the subject at http://dev2dev.bea.com/technologies/ejb/index.jsp

Peter: I concur with Phil. The issues are always with state and accessing/placing data in a data store, and architecting performant and scalable solutions involves choosing appropriate caching and concurrency strategies.

Phil: If its not the database, the hot spot will be where the application does other I/O.

When looking at requirements from a performance perspective I always try to bring "the physics" to the forefront. How many bytes do we need to transmit per request, and how many is that a second? What's the minimum number of database operations we could use to fulfil this business operation? Matrices of these simple metrics for key use cases weighted by expected frequency are a good way to compare and contrast the performance of different approaches whilst at the paper stage. As the design progresses, adding the resources (database tables, external systems) to the matrices and classifying the type of access (read-only, create, read/write) provides a useful model for examining contention patterns.

JPT: What are the most common performance related mistakes that you have seen projects make when developing Java applications?

Peter: I've seen several expensive mistakes come from not understanding transactions. The default transaction attribute is Transaction Required and most developers don't realize that this means every call between their web application and their EJBs will involve a brand new JTA transaction, which can be extremely expensive if a servlet makes many calls to entity EJBs.

I highly recommend that developers read Peter Holditch's regular column in the WebLogic Developer's Journal dedicated to transactions.

Phil: Yes, few J2EE developers seem to understand transactions and how they affect correctness of their application. Fewer still understand the implications that transactions have for EJB caching and performance. In Peter's example, every call into the EJB container will start a new transaction, typically do a database read, maybe a database write, then commit the JTA transaction and discard application tier state. This is especially sinful if the same EJB instances are accessed more than once. If instead an appropriate Session Facade is used to wrap all of the EJB work for the servlet request in a single transaction, the container will only issue one read (and perhaps one write) for each EJB instance that is used. Furthermore, the database interaction will be all or nothing, and is much more likely to be the right from the application perspective.

Peter: Then there's the classic sin of not doing performance testing until its too late. The methodology we developed for "J2EE Performance Testing" provides developers with a pragmatic approach that they can use from day 1.

Phil: This is one answer I give when people ask me whether they should use The Grinder or a commercial tool such as LoadRunner. (There are several others - $$$ :-)). Typically the LoadRunner licenses are in the hands of a performance testing team who begin testing late in the development life cycle, and never have enough time. The Grinder puts control right into developers hands and provides early visibility of issues. Its also easy to integrate into a nightly build process to measure how the performance of a system changes as the implementation evolves.

Not only does cheap and cheerful load testing allow immediate feedback when a performance issue is checked in, it also is a great way to find deadlocks, synchronisation bugs and other concurrency issues. When starting a performance engagement I set expectations: "You do realise we're going to spend the first week finding bugs?".

JPT: Which change have you seen applied in a project that gained the largest performance improvement?

Phil: Hmmm... so many stories. The other day I saw a carefully written bit of stream copying code, with a one byte buffer! I remember one customer's logging framework that (clumsily) parsed exception stack traces so that it could include location information in log messages. Disabling this (but still logging the messages) resulted in a thirty fold increase in throughput.

JPT: Have you found any Java performance benchmarks useful?

Phil: Benchmarking as a process is useful. As discussed earlier, I encourage my customers to do their own benchmarking and to do it early in the development process. Industry standard benchmarks are useful too, but only as marketing collateral. Of course BEA has to play the game, and we often as not lead. Perhaps if I had to front up the dollars I would pay closer attention to that great WebLogic/JRockit/Linux/Intel figure.

Peter: Industry performance benchmarks such as ECperf and SPECjAppServer are interesting when used to compare application servers. It is a constant leap frog game and the truth of the matter is that it does not help at all an architect/developer that is trying to make design decisions.

I strongly believe that the only benchmark that counts is one that is done with the application of the customer in the environment where it will run.

JPT: Do you know of any performance related tools that you would like to share with our readers?

Phil and Peter: Apart from The Grinder? :-)

Phil: Most problems can be identified with fairly primitive methods. Read the code, review the architecture and understand the physics, look at garbage collection patterns. What's the application doing with the database? Where is it likely to waiting on I/O? And my favourite - hit it with The Grinder and see what squeaks.

On some occasions I pull OptimizeIt or JProbe out of my tool box; they are both solid tools, but I rarely need them for J2EE systems unless I'm debugging a memory or thread contention issues.

JPT: Do you have any particular performance tips you would like to tell our readers about?

Peter: There are many, but I would like to concentrate on two fundamental aspects of approach.

First, do not spend to much time optimizing your code based on micro-benchmarks. You have to remember that your application is only a small part of the whole environment stack. Your J2EE application runs on top of a J2EE app server, which runs on top of a JVM, which runs on top of an operating system, which runs on top of a piece of hardware, which interacts with other systems typically via a TCP/IP stack. Tunning any component of this "stack" will have an impact on the performance of your application, be it positive or negative. Just don't loose sight of this bigger picture.

Phil: Yeah, leave your code optimiser in the box for most issues.

Peter: Second, and probably the most important is that the performance of an application (and this is for ANY application, not only Java or J2EE) is dependent of the way it is used, what I call the pattern of usage. No matter how much you have tuned the application and/or the stack where it runs, what finally decides its performance is the way the users are interacting with it. When you benchmark or performance test an application, make absolutely sure that you are replicating as close as possible the typical pattern of usage the app will be subject to. Any other kind of test will give you an idea of performance under conditions that are unlikely to occur. There are occasions you don't know what the real pattern of usage will be, so in this cases educated guesses are the only choice, but you should go out of your way to replicate as close as possible the way the application will be used to get a real picture of performance.

Thank you for your time. (End of interview).


Question of the month

Does using * in an import statement affect performance?

This question has come up a surprising number of times in various forums. The question relates to the import directive, as in

import java.util.*;

The short answer is: no, there is no affect on runtime performance.

The import directive is a compiler directive. The Java source to bytecode compiler reads the Java source file (i.e. a something.java file) and converts that source to one or more bytecode files (.class files).

Most Java source code in the Java source file is converted into Java bytecodes of one sort or another. But the import directive is not. The import directive specifically tells the compiler to do something. The import directive tells the compiler that when it comes across a class or interface name in the source file, e.g. HashMap, then if it cannot find the class file for that name, it should use the import statement to help it look it up. This way, you don't have to always use fully qualified class names, e.g. java.util.HashMap.

The import directives themselves do not get put into the compiled bytecode files. They are no longer of any use, as the compiler compiles the fully qualified name into the .class file.

For example, suppose the source file contains

import java.util.*;
//
...
   HashMap map;
...

Then the compiler gets to the HashMap map variable declaration, tries to find a class called HashMap in the default package (i.e. no package name), fails, and uses the import statement to see if there is a java.util.HashMap class. This is found, and a reference to java.util.HashMap is inserted into the .class file. After compilation is completed, there is no use for the import directive, so it is not present at all in the compiled bytecode. Consequently, the import directive cannot affect runtime code execution in any way.

However, it is worth noting that the directive does affect compilation time. Since the directive tells the compiler how to do a second lookup to find classes, obviously this means that more time is spent looking up class and interface names compared to if one lookup sufficed.

In fact, there are two forms of the import directive: with and without the wildcard '*', e.g.

import java.util.*;
import java.util.HashMap;

Without the wildcard, the directive tells the compiler to look for one specific file in the classpath. With the wildcard, the directive is telling the compiler to look for the named package, and to search in that package for possible matches everytime any name needs to be matched. This latter version is probably going to be more costly (i.e. take longer) for the compiler than the former.

Also, depending on which compiler you use, and which settings, the compiler may re-compile all of the classes in the wildcard package, which could really make things take longer.

Finally, many people find that using imports with wildcards makes the source much less readable, since the reader also needs to figure out which package a particular class comes from, rather than just looking it up in the import statement.

So the full answer is

The JavaPerformanceTuning.com team


Tips

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3054.pdf
Case Study of a High-Volume Account Servicing Application Using J2EE Technology (Page last updated June 2003, Added 2003-06-25, Author Carol McDonald, Joseph Paulchell, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3014.pdf
How J2EE Technology, Open Standards and Open Source Brought You the Architecture of the Miller Time Network (Page last updated June 2003, Added 2003-06-25, Author John Haro, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/1440.pdf
Graphics Performance Writing Optimized Client Applications (Page last updated June 2003, Added 2003-06-25, Author Scott Violet, Joshua Outwater, Chet Haase, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/2879.pdf
Performance Tuning the Sun ONE Application Server (Page last updated June 2003, Added 2003-06-25, Author David Dagastine, Eileen Loh, Scott Oaks, Martin Zaun, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3600.pdf
Optimizing EJB Performance in High-Volume Data-Warehousing Applications Patterns, Strategies and Best Practices (Page last updated June 2003, Added 2003-06-25, Author Samrat Ray, Arunabh Hazarika, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3264.pdf
A Billion Hits a Day (Page last updated June 2003, Added 2003-06-25, Author Deepak Alur, Rajmohan Krishnamurthy, Arnold Goldberg, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3099.pdf
Measuring Java 2 Platform, Enterprise Edition (J2EE) Application Performance in Production (Page last updated June 2003, Added 2003-06-25, Author Geoff Vona, Publisher Sun). Tips:

http://servlet.java.sun.com/javaone/resources/content/sf2003/conf/sessions/pdfs/3153.pdf
Garbage Collection in the Java HotSpot Virtual Machine (Page last updated June 2003, Added 2003-06-25, Author John Coomes, Tony Printezis, Publisher Sun). Tips:

Jack Shirazi


Last Updated: 2018-11-28
Copyright © 2000-2018 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
URL: http://www.JavaPerformanceTuning.com/newsletter031.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us