Back to newsletter 048 contents
In case you've not already seen it, Sun is working towards Mustang. To support the effort, they have opened up a forum to allow the "community" to offer suggestions on what features you'd like to see in Java. Although it's nice that Sun is out looking for suggestion I am sceptical of the value of such a forum. The forum inspires a lot of passion in people as they argue for this feature or that. But in many cases, it is questionable how much experience any of the participants have in language design. There are hundreds of computer languages in existence but there are only a small number that have made it into wide spread use.
It is difficult to say what makes people/businesses adopt one language over another. It is also not clear how much one can extend a language without destroying the character or violating the design principles under which is was originally designed. Historically we have two examples that we can look to, FORTRAN and Basic.
Fortran is still in use, though it no longer maintains the large mainstream support that it once did. Though it has gone through many changes, those changes were really limited to clarifications of existing syntax. For example, if-else statements replaced the need for the goto. On the other hand, Microsoft has given Basic a whole new look as it moved the language from its roots to QuickBasic and then along to Visual Basic. It added a number of quasi-OO structures to help facilitate the move from the functional world. Even though the roots of the language are still visible, VB is sufficiently different enough from Basic that one could make an argument that it really is no longer Basic.
The common thread in the evolution of FORTRAN and Basic is that the changes moved the languages forward as new techniques and mechanisms where discovered and incorporated. Why Fortan floundered and VB flourished is another multi-dimensional tale but one thing is clear, it wasn't for reasons of performance. To this day, it is still accepted that no general purpose compiler produces as efficient machine code as the FORTRAN compiler does. This was certainly true when I was writing code for Crays. C contained many structures that made it difficult if not impossible to apply "safe" optimizations. C++ further compounded the problems. Thus code written in C++ generated machine code that was generally 40% less efficient than that generated by C which was another factor away from that generated by FORTRAN. But in spite of these, we choose to use the "less efficient" language because it was much more expressive.
Now with Mustang (and indeed with the 1.5), we are starting to see pressures to alter the language in many different ways. Unfortunately what is missing in a majority of suggestions are syntax that advance our ability to express solutions to complex problems. Instead we are being inundated with features found in C++ that the designers of Java purposely left out of the language and for good reasons.
Java is a simplification, which is what makes it work as well as it does! Though it is clear that the language will change, we must be careful what changes we make. We need to understand the motivations for the change: does the change really match the motivations, are the motivations genuine, or do they reflect a perceived need that is not real. How will the changes affect the language, will they really make things easier or will they offer hidden obstacles. The list of questions goes on but they need to be asked and answered before we alter the basic contract that we have with our computers, the Java Language Specification.
Starting this month, after feedback from several of you, I've decided to include the link to the threads of discussion that I've summarized or commented on. It's an addition that is so obvious that I don't know why I missed it in the first place. Thank you for your suggestions, please keep them coming.
The month we start off at Java gaming with a questioner asking what might cause a long pause. Now a long pause for this group is typically no larger than a few 10s of milliseconds so it was quite surprising to see a discussion where the pause lasted in the order of seconds. Furthermore, the effect was demonstrated in a number of Java applications running in the JDK 1.5.0 on W2K that relied on graphics. This list includes JEdit, JBuilder and Eclipse. It was quickly determined that this pause occurred while running the application in the new JDK and was not observed in previous versions. Though many suggestions were offered, none of them offered a valid explanation. The most promising point was made regarding the movement of the windows cursor. Apparently, Windows gives the cursor thread a priority that cannot be matched by other processes. The current working hypothesis is that Java is grabbing exclusive access to something in the kernel that is causing all other applications to lock. Could this possibly be a bug in Java?
From the JavaRanch we have a newbie question that offers up some information of interest for all. The question asks if there is any performance advantage to declaring a computationally intensive method static. The short answer is no. Though it may seem like an advantage to resolve a reference such as a method call statically (via the compiler), with HotSpot, the call might be eliminated altogether. Thus the best option is to choose the solution that best fits your design. In a large majority of the cases, methods should not be declared static. The last post asks a very leading question, does the cost of the call really matter if the method is computationally intensive?
The question of Enumeration vs Iterator has been discussed before but as is often the case with extra long discussion threads, this one got side tracked. The question during the process of discovery became, what is the cost of declaring a variable inside of a loop as apposed to declaring it outside of the loop. Consider the following code fragments.
//Listing 1. Declaring a variable outside of a loop. Object o; for (int i = 0; i < someValue; i++) o = new Object(); // //Listing 2 Declaring a variable inside a loop. for (int i = 0; i < someValue; i++) Object o = new Object();
Interestingly enough, the compiler will move the local variable declaration in listing 2 to the outer scope so that both code fragments will produce identical byte code. Even though much of the effort to optimize code has been moved to HotSpot, the compiler still plays an important role in optimizing code.
One noticeable difference this month is that there were a number of questions regarding how to profile J2ME code. Is this a sign that Java is making yet more in-roads onto other devices? Curiously, there doesn't seem to be a profiler that will work while the application is actually running on the device. This leaves one to profile (and it's not clear that this is even possible) while running in the emulator. I'll admit that it's been a long time since I ran J2ME code in a profiler. If I recall, that emulator was great for functionality but not so good for performance. There is hope; one response came from someone building a J2EE profiler for JBoss. Apparently they believed that it was possible to build an adaptor for the device that would allow one to profile the application while running on the device.
First, in this never static world we face yet more change. The Middleware Company has been sold and thus no longer controls TheServerSide. It shall be interesting to see what affect this has on the site though I suspect that the community is strong enough that it will continue to be a "go to" site for information.
We start this month with a question regarding NIO
performance. For those of you who maybe unfamiliar with the NIO
Selector class; that class is designed to
select() functionality offered from the operating system.
To use the select() function, you
must provide a bit mask where the index of the bit set is determined
by the file number offered by the OS. There is one mask for those
files for which you are interested in reading from and another for
those for which you are interested in writing to. Once you make a
call to select(), your thread may or may not block (depending on a timeout parameter),
until the kernel notifies that at least one of the
files described in the bit mask has become readable/writeable. This
information is returned in another set of bit masks that you must
In Java, the blocking behavior resulted in a server application needing one thread to service each client. This posed a limit on scalability of server applications. The introduction of an API that exploits the underlying select() functionality breaks this one-to-one requirement, and allows server applications to service many more clients than they would otherwise be able to. For more information, try http://javanio.info/
What is the maximum number of sessions a webserver can handle? It's a good question and unfortunately, the answer is, it depends upon the requirements of your application and the limitations it places on your ability to utilize available hardware/software technologies. Though upper bounds of the answer would appear to have been set by eBay and other high volume sites, these sites have natural separations in their domain that allow them to scale horizontally. Other sites scale by eliminating or limiting the amount of state that is maintained on the server. It is this state that will dictate the scalability as it needs to be accessible until the user logs off or a timeout is reached. The most common technique used to make this session information available is to cache it in a database. Other options involve using a distributed caching technology. There currently are a number of good options available. Another solution is to use server affinity. Though this solution does work, it has reliability drawbacks. All of these solutions rely on the application not having a single point of contention across the entire application. What ever solution you choose, eliminating points of contention should be your primary focus.
Back to newsletter 048 contents