[an error occurred while processing this directive]
This month we have a nice crop of JDBC tuning articles; more on J2EE performance and scalability; a couple of articles on optimizing embedded Java; and several articles delving into core Java including SoftMaps and Enumerations. The animation/games focused article this month comes from Java3D, listing tips from the J3D mailing list; and in the news section there is an interesting article from a C++ games programmer who has converted to Java.
In addition there is one more article that I found particularly fascinating, as it is the first article I have seen which addresses audio performance ("Writing a seamless audio looper").
Kirk covers the interesting discussions over the last month, and adds his view on the prospects for the latest incarnation of GemStone. And finally here's my usual reminder to our Japanese readers that Yukio Andoh's translation should be available at http://www.hatena.org/JavaPerformanceTuning/ in a while.
Java performance tuning related news.
All the following page references have their tips extracted below.
As the dot bombs continue to super-nova, in addition to the many people being jettisoned, some interesting technologies are also being dumped. Such was the case with Brokat Technologies (BROA) when they sold their Blaze Soft and GemStone divisions for 20M USD and 1.7M USD respectively. It?s been about one year since Brokat exchanged 550M USD in stock for Blaze and 250M USD in stock for GemStone. GemStone has a twenty-year history building application servers. Their first large commercial offering was a very scalable Smalltalk application server (GSS). In October of 1997, GemStone offered the first version of their Java application server, GSJ. Since GSJ shares the same fundamental architecture as GSS, it is arguably, the oldest piece of Java technology on the planet.
While BEA was pouring on the marketing and pushing WebLogic to support the latest and greatest spec, GSJ lagged behind. Brokat decided to release an EJB 1.1 compliant GSJ and put its GemStone division into maintenance mode. The version was never even released. At 1.7M USD, buying GemStone should be a safe bet. The J2EE/EJB server market is just coming to understand the scalability issue, GemStone?s sweet spot. This makes it the right time to re-energize GemStone.
[editorial note: Kirk had been intimately involved with GemStone for many years until recently. Given the established scalability of the product, many of us were sad to see the company being slowly dismantled by Brokat, so hopefully new ownership will give GemStone a new lease of life.
For those of you interested in the financials: the 250M USD of Brokat shares used to acquire GemStone has a current share value of about 5M-10M USD. When Brokat acquired GemStone it was profitable, with at least 20M USD turnover.]
If you take a walk to the saloon at the Java Ranch (www.javaranch.com), you?ll find the usual array of regulars mixing it up with the latest batch of greenhorns. This months offering includes an interesting question on the
import statement. The question: does using the wild card * have any impact on performance? The answer is no (at least not for runtime performance). Well, then, why bother to explicitly import classes? That question leads me to two of my other favorite topics, readability and metrics. Programming languages were written for human readability. Explicitly importing classes allows me to quickly determine what a class is using. One metric that I rely upon during a tuning exercise is the level of coupling in the code. From experience, I know, the higher the level of coupling, the more fun I?m going to have after I?ve made some changes. Looking at the number of import statements in a class helps to understand just how much fun I?m going to have. Using * makes it much more difficult to eyeball this metric. When I?m coding, if I see a certain depth of import statements, then I start asking the question, is this class doing too much. As a final point, using * does add a little (very little) extra performance overhead during the compilation phase (
import is a compiler directive, not a runtime bytecode).
One of the ranch hands ran 4 applications in the same VM and noted a 60% overall reduction in memory usage. He was curious as to why this might be. The answer is that all of the applications were sharing many of the same classes, and much of the JVM overhead. Many application severs use this technique to allow deployed applications to share common classes. You need to code with care as the
Class.forName("MyClass") can cause
ClassNotFoundException to be thrown. I recommend always using
Class.forName("MyClass", true, Thread.currentThread().getContextClassLoader()) as this will allow classes loaded in a parent class loader to see classes loaded by it?s children.
This months Java Gaming (www.javagaming.org) offered one very interesting question. How many of the published Java performance tuning tips are still valid given the recent improvements VM technology. The recent addition of generational garbage collection certainly has changed the picture on object creation and pooling. In my opinion, object pooling has dubious benefit. Recent advances in VM technology should eventually eliminate the need for this level of hack. Most predominantly is the advent of generational garbage collection. The thread provides an excellent description of how this all works. The best advice given was to use a profiler to determine if object pooling was really providing you with enough of a benefit to justify the complexity and cost.
In addition, the C++ comparison question (troll?) migrated to JavaGaming. This led to a spirited discussion, which seems to have adjusted the opinion of the original poster that pure Java was now sufficient for writing games (as reflected in his article).
Finally, outside the performance forum, Niels Jørgensen describes how using a DirectColorModel with no alpha channel (
new DirectColorModel(32,0x00ff0000,0x0000ff00,0x000000ff)) along with MemoryImageSource.newPixels(), speeded up image drawing considerably compared to using the default color model. The thread (
JavaGaming.Org Message Board: 2D Graphics Programming in Java: AWT: Oddities of drawImage()
) covered some more detail on how to use newPixels().
For my last discussion group, lets check out the Middleware Company at www.theserverside.com. There was an interesting thread regarding JDBC connection pooling. A participant reported that Allaire is making recommendations not to use connection pooling in some situations. The argument reportedly made by Allaire, is that enterprise DBs already pool the connections on the DB, which is more efficient. The problem with this claim is that a connection has two ends. Another reader correctly pointed out that Allaire?s claim was not to use their connection pooling when using a JDBC 2.0 compliant driver (see the article on Connection Pooling with JRun listed in the tips section of this issue).
Another thread asked about EJB performance vs. JDBC direct calls. This question must appear more times in more lists than just about any other. It would be safe to say that EJB performance can be, at most, no better than using direct calls and, at worst, considerably slower. The reasoning? In both cases, you?re storing data in an object to a relational DB using the same SQL. Using EJB architecture places a framework between you and the data you want to store. Hence, there is an added cost to using an EJB. But, the industry considers EJB technology to be good enough to cover the cost. In many applications, the benefits of using EJBs does outweigh the performance cost.
And finally, a story was related to me. A consultant was asked how fast his company?s middleware would go. The consultant responded with, "how fast does your bicycle go?". [time to get out the CPU hand-cranker - ed.]
EJB2.0 Container-Managed Persistence (Page last updated July 2001, Added 2001-08-20, Author Beth Stearns). Tips:
Optimizing JDBC (Page last updated August 2001, Added 2001-08-20, Author John Goodson). Tips:
Connection.prepareCall("Call getCustName (?)").setLong (1,12345)rather than
Connection.prepareCall("Call getCustName (12345)")
J2EE clustering (Page last updated August 2001, Added 2001-08-20, Author Abraham Kang). Tips:
SoftReference-based HashMap (Page last updated August 2001, Added 2001-08-20, Author Heinz Kabutz). Tips:
Writing a seamless audio looper (Page last updated August 2001, Added 2001-08-20, Author Greg Travis). Tips:
Performance tuning embedded Java (Page last updated August 2001, Added 2001-08-20, Author Vincent Perrier). Tips:
Java 3D performance tips (Page last updated June 2001, Added 2001-08-20, Author Doug Twilleager). Tips:
Optimizing JDBC Prepared Statments. Also a followup discussion at http://www.theserverside.com/discussion/thread.jsp?thread_id=8013 (Page last updated July 2001, Added 2001-08-20, Author ?). Tips:
Connection Pooling with JRun (Page last updated June 2001, Added 2001-08-20, Author Karl Moss). Tips:
Caching (Page last updated July 2001, Added 2001-08-20, Author Jonathan Lurie). Tips:
BigDecimal and Enumerations (Page last updated August 2001, Added 2001-08-20, Author Glen McCluskey). Tips:
Flicker-free graphics with the Mobile Information Device Profile (Page last updated July 2001, Added 2001-08-20, Author Eric Giguere). Tips: