In his article about the util.concurrent package, Brian Goetz points out that "Most of us would never think of writing our own XML parser, text indexing and search engine, regular expression compiler, ...". We use existing standard packages. The open source community does sometimes recreate standard tools for a very good reason: to make them open source. But it gets a bit ridiculous when we end up with four versions of slightly different open source tools. This seems to the situation with Java profilers. We now have at least four open source versions, (jcoverage, EJP, jProf, simpleprofiler) all seemingly in alpha release. They are of varying ages, going back to 1999. As each one successively became unsupported by its author, it seems like the next one started being developed by someone else. Why?
The quality of articles being written is still impressive this month. My own article on nulling and GC was well received; Brian Goetz's article on util.concurrent, the first of a series, is excellent as usual with Brian. If garbage collection (GC) is of interest to you, Nagarajayya and Mayer have updated their GC tuning article to cover 1.4.1. The article is well worth reading in detail: 1.4.1 includes five (yes 5!) garbage collection algorithms, and the article explains their aims and interactions.
I don't normally list research articles that don't have concrete performance tips. But I've made an exception for Vivek Haldar's research paper on verifying compile time assists for JITs (actually entitled "Verifying Data Flow Optimizations for Just-in-Time Compilation"). Since 1.1, compile time optimizations have been gradually reduced until the -O does nothing, mainly because the JIT knows more at runtime and can apply better optimizations then. I've been waiting for techniques to appear which will reverse this process of leaving everything to runtime, after all at compile time you have far more time to do optimizations. Now Haldar's paper shows how the compiler can add optimization hints while still satisfying the Java security model, which was probably the biggest sticking point.
Otherwise, we list a number of other articles covering EJBs, servlets, JDBC, XML parsing, web services, performance monitoring and analysis, J2ME design and portability, and more.
The roundup and Javva are also here, and our interview this month is with Ed lycklama of Sitraka (now part of Quest), who gives us his interesting view of Java performance. And we also have all the new performance tips extracted from our listed articles.
Java performance tuning related news.
A fascinating question on garbage collection in a Weblogic server offered some insight to high performance JMS issues. The messages being fired into the JMS queue were not being collected quickly enough, so memory usage continured increasing until out-of-memory was reached. The questioner had changed his system to use (Weblogic) message paging, which limits the number of messages held in the in-memory JMS queue, queueing further pending messages on the disk. As long as the messages did not have to be processed at maximum speed, the case in this application, then this is an acceptable solution. However, the problem that remained was excessively long garbage collections. To solve this problem, the respondants mostly suggested contacting Weblogic support. But a couple suggested using -Xincgc, the incremental GC option, which breaks GC into smaller chunks to minimize GC pause times. We never found out if this worked.
Another thread posed the interesting problem of needing to access a collection of objects in two ways (in this case by rank order, and by ID). The question was, how should the the array be sorted, and would a linear search provide adequate performance. Suggestions included: using two structures to redundantly store the data, e.g. ArrayList for the sorted access and HashMap for ID access; using an ordered Map such as TreeMap or LinkedHashMap; or simply using one sorted list and using linear search for small collections.
And the last thread that I'll look at this week from JavaRanch posed a similar data structures question. In this case the developer was looking to see if certain fields were present in each of three files containing up to a million records. The only responder to this question, Jim Yingst, gave a thorough analysis of the problem, pointing out the memory problems of searching through that amount of data, suggesting sorting the files and comparing them a fragment at a time, possibly using an external index structure to maintain a sorted order if direct sorting of the files was not possible.
In my first professional programming position I remember watching an external expert and internal expert jousting over some code that was being put together to demonstrate a product. It looked like watching a couple of wizards at work, concocting some esoteric spell. I had that impression once again when reading the JavaGaming discussion about the optimum tile size to use in Java. Here were the animation experts, deciding on how best to draw tiles. It seems that the BLT call is the expensive bit, not the size of the tiles; background buffers BLT'd to screen using offsets are the way to handle changes in perspective; VolatileImage is essential, though not yet fully effective on Linux and not fully supportive of transparent images; and 2D games should use the 3D API, which gives you all you need plus many extra options for free.
Still in with the wizards, this time we have a Sun engineer (another one, apart from the ubiquitous Kesselman) informing how to draw scaled images the fastest. It turns out you may need to enable some forms of hardware scaling, you need to specify -Dsun.java2d.ddscale=true. Using -Dsun.java2d.trace=log helps to see what 2D primitives are being used. But the real gold was that Image.getScaledInstance() has some major performance issues, and you should get an image with Component.createImage() or GraphicsConfiguraton.createCompatibleImage(), and use one of the Graphics.drawImage() calls (which scales on-the-fly) to render your source image to the new image.
Does explicitly setting variables to null help garbage collection? This discussion, with a very good example, showed that there were cases when this was true. In particular, an example was given where Eden was full and an object could theoretically have been reclaimed to make space for a new object, since the new object was being reassigned to the data member variable holding the theoretically reclaimable object. But the reclaim couldn't happen because the data member variable still referenced the reclaimable object, preventing it from GC'd. Consequently, the object was promoted to old generation space, and later required a full mark-sweep GC to reclaim it. The same example with the data member first explicitly nulled was also tested, and showed a huge improvement in speed. The whole discussion is further summarized and extended in this article.
A question that comes up time and again is CMP vs. BMP performance. This time round, the question lead to the most inetersting discussion I've seen. The question, summarized elegantly by the originator:
Clearly BMP means I need to write the persistence layer, but I am confident the system will perform because I write the carefully crafted joining SQL for reading. CMP will reduce our codebase and sounds like Utopia... Can CMP really perform, or are we better staying with BMP supported by various data access patterns?This seems to have elicited some quality answers. The first reply suggested that the issue is more whether to use stateless session beans with JDBC, or entity beans. I agree with that poster that frequently EJBs are used when they are unnecessary, so this alternative should always be looked into. Several subsequent posters suggested that BMP will always be faster if you have optimized it for your own particular application needs. One poster also pointed out that it is not really an either/or situation. Development tools can change a BMP bean to a CMP bean quicker than you can write this line. Finally, the most comprehensive reply from Stephen Kosravi stated: "CMP all alone won't help you, the whole EJB critical path has to be optimized." Kosravi went on to suggest prototyping the two solutions for their particular needs, and also gave a recipe for good CMP performance:
Another poster asked whether JRockit was any good since the idea of a dedicated server-side JVM made sense to him. The only reply suggested that JRockit performed similarly to other JVMs, though the performance was highly dependent on the application. My advice is to try every JVM you have access to with your application. I can guarantee that they will all produce different performance, and that one will be the overall fastest for your application.
The final thread I'll look at asked about the performance gains from clustering the servlet layer and the EJB layer separately. Did the gains from the separately scaled layers outweigh the losses from making all servlet/EJB class remote? Well, there was no answer from anyone who had actually done this, but the sole reply from Joe Hoffman did give a good rationalization to suggest that: "the larger the system is, the more sense it makes to specialize certain VM's to certain tasks. In small systems, this specialization probably doesn't make much sense and is not worth the complexity."
During the dot bomb, I was the CTO of a fantastically successful startup. Well, okay, the company was a couple of guys I knew, no employees, and we almost got first round funding before the stock market meltdown. I didn't even give up my day job. But the thrill was unbelievable, and can you blame me for trying to get on the bandwagon? One day we were talking to VC guys about $10 million, looking forward to becoming overnight paper millionaires and adding our great products to the world economy; the next day they didn't remember ever meeting us and we were back to being joe nobodies. I don't like real roller coaster rides, but looking back on it, this virtual one was kinda fun.
Over on DevX, they have The diary of a startup. If you are at all interested in the startup business process, this is one way to live someone else's ride.
November 13. Damn, what were those guys thinking! Bloody Pet Store
might be a bloody toy application but they're making bloody waves! Of course
I'm the performance expert here, so I have to explain
up the chain why Java is faster and no we don't
need to start evaluating DOTNOT to see if we should be implementing
this and no there's no need to re-evaluate our
forward plans on that and ... Scrrrrreeeeeeeaaaaaammmmmm!!!!
What the hell did they use to profile the application?
Why do I have the strong feeling that I've just been royally
screwed when a company that I didn't commission has tested a
non-benchmark application against another system that I don't
care about using incompetent procedures and inexperienced engineers
to provide a pointless comparison. And why am I having
to spend lots of time explaining all this here!!!
November 20. No freebies yet. What kind of salesman doesn't give away freebies worth a tiny fraction of their product to close the deal? Either these guys are better than I thought, or our industry is doing much worse than I thought. Can anyone reading this tell me if companies have ruled out giving away freebies now?
November 28. Jack's comments on the Pet Store fiasco (November newsletter) were spot on. Someone at Microsoft probably got a big bonus for this PR job. Oracle's implementation 20 times faster than Microsoft's! How come no one else is publicising that? Well at least I can point my bigwigs to that.
Javva The Hutt.
This month we got to interview Ed Lycklama, previously the chief technology officer and co-founder of Sitraka. Ed is recognized as an expert in Java technology-based application performance issues, and JavaPerformanceTuning.com asked him some questions on Java performance.
Q. Can you tell us a bit about yourself and what you do?
Sure. I?m the Chief Architect, J2EE Solutions for Sitraka, which has recently been acquired by Quest Software. My responsibilities include providing technical direction for Quest?s J2EE performance management strategy, and interfacing with product groups to define J2EE product integration strategies.
Q. What do you consider to be the biggest Java performance issue currently?
Java applications run in a variety of environments (everywhere from hand-helds to huge mainframes) and the performance challenges are very different for each. With server-side applications written for J2EE application servers, the performance challenges typically revolve around excessive or inefficient accesses to backend systems such as databases, naming directories, and mainframe systems.
Q. Do you know of any requirements that potentially affect performance significantly enough that you find yourself altering designs to handle them?
Many enterprise-class applications include a requirement to support a large number of concurrent users. I have yet to see the implications of that requirement spelled out in detail. In general, a large number of concurrent users increase the contention on critical resources. Any exclusive access to those shared resources should be streamlined to avoid unnecessary queuing. Finding ways to avoid accessing that resource by employing a data caching strategy will also reduce overall contention.
Q. Can you tell us a little about Sitraka's products?
With several award-winning products that help companies to pinpoint and eliminate performance hazards in mission-critical J2EE applications Sitraka, recently acquired by Quest Software, has been a long standing leader in the Java market. Products include PerformaSure, a transaction-centric J2EE diagnosis solution, JProbe performance tuning tools, JClass Java components and DeployDirector, a Java application deployment solution.
Q. How has the acquisition affected things?
The combination of Quest and Sitraka enables us to offer customers additional value in the form of a leading application management product set that spans the application life cycle, all from a single-source supplier with a global infrastructure and public company accountability.
Customers can rest assured of business as usual at Sitraka.
Q. What are the most common performance related mistakes that you have seen projects make when developing Java applications?
Well, as stated in a previous answer, one of the biggest mistakes is failing to take scalability requirements into account when designing the overall application. Failure to do so can result in last-minute fire-fighting disasters, threatened deployment dates, alienated customers and exploded budgets.
Q. Have you found any Java performance benchmarks useful?
I?m not a big believer in performance benchmarks, especially in areas as complicated as J2EE applications that span diverse computing platforms and interact with legacy applications.
Q. Do you know of any performance related tools that you would like to share with our readers?
I?m glad you asked that! Let me tell you a little more about our two product families focused on J2EE performance.
PerformaSure is a transaction-centric diagnosis tool that helps companies to measure, analyze and maximize performance of multi-tiered J2EE applications during load testing and before costly problems occur in production.
JProbe is a comprehensive, award-winning toolkit for diagnosing code errors and inefficiencies. With performance profiling, memory debugging, thread analysis and code coverage tools, JProbe paints graphical pictures of everything from memory usage to calling relationships, helping developers understand precisely what is causing problems in a Java application - right down to the offending line of source code.
Together, PerformaSure and JProbe provide a highly targeted solution that enables rapid identification and repair of business-threatening performance problems.
Q. Do you have any particular performance tips you would like to tell our readers about?
How about some advice: every application is different, and will have its own performance and scalability issues. The only way to determine what those issues are, and how you can get the most out of your application (whether that means supporting more users with less hardware, or delivery responses more quickly), is to measure your application with realistic scenarios and use a highly targeted performance assurance solution to identify and eliminate costly performance problems. 0bviously I?d like to recommend PerformaSure and JProbe - but in any case - use something: remember, if you can?t measure it, you can?t fix it.
(End of interview).
Does nulling variables help garbage collection (Page last updated November 2002, Added 2002-12-27, Author Jack Shirazi, Publisher Kabutz). Tips:
The util.concurrent package (Page last updated November 2002, Added 2002-12-27, Author Brian Goetz, Publisher IBM). Tips:
Optimizing EJB validation code (Page last updated December 2002, Added 2002-12-27, Author Brett McLaughlin, Publisher IBM). Tips:
Long-running tasks (Page last updated November 2002, Added 2002-12-27, Author Serguei Eremenko, Publisher Builder.com). Tips:
CPU usage monitoring (Page last updated November 2002, Added 2002-12-27, Author Vladimir Roubtsov , Publisher JavaWorld). Tips:
Application server performance (Page last updated November 2002, Added 2002-12-27, Author Rohit Valia and Marina Sum, Publisher Sun). Tips:
J2ME portability (Page last updated December 2002, Added 2002-12-27, Author Jeremy Wakefield, Keith Braithwaite & Tony Robinson, Publisher JavaDevelopersJournal). Tips:
J2ME design patterns (Page last updated December 2002, Added 2002-12-27, Author Ben Hui, Publisher JavaWorld). Tips:
Tuning 1.4.1 heap and GC (Page last updated November 2002, Added 2002-12-27, Author Nagendra Nagarajayya and J. Steven Mayer, Publisher Sun). Tips:
EdenSize = NewSize - ((NewSize / ( SurvivorRatio + 2)) * 2)and
SemispaceSize = (NewSize - EdenSize) / 2).
Java Performance for DB2 Applications (Page last updated November 2002, Added 2002-12-27, Author John Campbell, Publisher IBM). Tips:
Caching web services (Page last updated December 2002, Added 2002-12-27, Author Brian D. Goodman, Publisher IBM). Tips:
Statistical analysis to help identify performance bottlenecks (Page last updated November 2002, Added 2002-12-27, Author ProactiveNet, Publisher ebizQ). Tips:
Compile time assists for JITs (Page last updated October 2002, Added 2002-12-27, Author Vivek Haldar, Publisher Sun). Tips:
Building a lightweight XML parser (Page last updated November 2002, Added 2002-12-27, Author Guang Yang, Publisher DevX). Tips:
Safe data writing with memory mapped files (Page last updated November 2002, Added 2002-12-27, Author Greg Travis, Publisher DevX). Tips:
Comparing The Performance of J2EE Servers (Page last updated November 2002, Added 2002-12-27, Author Christopher L Merrill, Publisher Web Performance Inc). Tips: