Back to newsletter 024 contents
First off, I thought I'd check out the other general performance discussion groups listed at http://www.JavaPerformanceTuning.com/resources.shtml#Discussions. There are a couple more beyond JavaRanch/TheServerSide/JavaGaming. Well, those others are all dead, so that was quick. Now on with the active three.
The question of what resources are available for performance tuning Java apps comes up periodically in the various discussion groups. This time it was the JavaRanch's turn, but the discussion groups seem to take turns in having some new denizen pop up and ask this question. Of course the answer is to look on the JavaPerformanceTuning.com resource page. The only real question for me is how many posters reply to the original question before this definitive answer ends the discussion. Increasingly that number is one.
A question on encryption performance came up. This is pretty rare, I can barely remember any questions on encryption performance previously appearing. I can remember those few times that the question has been raised, the answer was "encryption is slow". This time, Mark Herschberg gave a more useful answer that "public key encryption is far more expensive then symmetric key encryption". He went on to recommend hybrid SSL solutions: "create a symmetric key for each session and first send it using a public key encryption scheme. This means you only need public key encryption in the beginning of the protocol, and the rest of the time you use the faster symmetric encryption". Sounds like a pretty good compromise.
Would making everything possible
final improve performance?
Responses to this question suggested that possibly it would have in earlier
Java implementations, but in more recent implementations HotSpot does the
kinds of runtime code analysis that means using
not give any significant performance boost. Some interesting analysis
of what HotSpot does in different situations followed, producing the
interesting result that HotSpot keeps track of when a method
must remain polymorphically called, and hence has a high runtime call
overhead; and when a method can be statically called (which is the
supposed performance benefit of using
final), so can be
called much more quickly.
Finally, a developer looking for help with garbage collection of windows
was given the useful advice that he should be calling
on his windows to release the resources. Two hours was all that was needed
between the original question being posted, the resulting comments and the
original poster psting back that it had worked. Now that's efficiency for
As an aside, the same thread generated further discussions on how implementing finalizers are bad for performance because the object hangs around for longer and puts more work into the GC thread; and also about how explicit gc() calls should be used very carefully (i.e. not at all) so as to avoid adding further overhead to the system.
JavaGaming is going through a reorganization at the moment, but the old discussion forums are available as archived discussions, and new discussions can be started in the new section of the site. For the moment I'm still running through the old discussions.
Over in the gaming performance forum one poster was asking how to speed up his 2-D interpolation algorithm. It turned out that he was painting each pixel individually when he should have been painting them in a block. A code fragment showing how to manipulate the pixels and get the resulting image was given:
ColorModel cm=new DirectColorModel(24,0xFF0000,0xFF00,0xFF); int pixels = new int[x*y]; source = new MemoryImageSource(x,y,cm,pixels,0,x); source.setAnimated(true); Image output=Toolkit.getDefaultToolkit().createImage(source);
The poster who gave the answer also pointed out that BufferedImage was what should be used in Java 2, but was not available for 1.1 (which the original poster specified). This resulted in further discussion as to whether gamers should carry on supporting 1.1, because of MSIE, or whether 1.1 support should be dropped in order to encourage upgrades to be made. The resulting posters seemed to be split fairly evenly as to their preference.
A huge thread was started by one developer of a Z80 emulator finding that the old (1.1) MS JVM ran his emulator significantly faster than the latest Sun JVM. He tried to show that local variable access was the problem, using a microbenchmark. However, it turned out that most of the difference in performance was due to the coding style. The results of the thread:
Finally, an old discussion on GC was given new life by a poster asking about
his code. The older discussion produced an interesting idea: to minimize GC pauses,
you can deliberately retain references to objects so that the GC cannot reclaim
those objects, hence causing fewer shorter pauses for the program. The thread also
requested Sun to introduce a GC algorithm with explicitly settable limits on pauses.
The newer thread threw up the interesting logging parameter for tracing core 2-D
The Server Side produced its usual crop of challenging enterprise performance questions. First up was an interesting question on Weblogic pooling, coupled with queries possibly producing 50,000 records from the database. One poster wrote "If you have employees who can read and do anything useful with 50,000 rows of data I would love to hire them". Basically, the advice was to use stateless session beans, with a separate data access layer to obtain the database rows. Further suggestions inlcuded lazy initialization, data on demand and fetching only a few rows at a time, holding a marker of which rows have been accessed so that future continuation accesses from the same client could start from that marked row, using a query like
SELECT ID, COL1, COL2 FROM MYTABLE WHERE ID > ? ORDER BY ID
Another question on how to improve JBoss performance produced a list of generic tuning tips:
Another thread asked which resources to monitor for improving performance. This gave another useful list: Garbage Collection, HTTP sessions, ORB threads, JDBC Connections, CPU utilization and hardware memory, all pooled resources (make sure you are not exhausting your free elements in the pool). Further useful advice included suggesting running the system over a long period of time with varying load, and adjusting pool sizes to accomodate the expected load.
Finally, a very brief discussion on commit options: commit option A reduces I/O overheads but limits concurrency; commit option C supports a higher level of concurrency but has higher I/O overheads.
Back to newsletter 024 contents