Back to newsletter 031 contents
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).
Back to newsletter 031 contents