There have been a few AOT compilers for Java for some time. Two of the better known examples are GCJ and Excelsior JET. Even though Excelsior JET also has a JIT, the main focus was on the AOT aspect.
There have been many suggestions that HotSpot should cache the JIT-generated code to improve start-up performance, avoid the need for a warm-up phase on every invocation of the application and possibly share more data between applications. This is particularly relevant for desktop applications. HotSpot engineers claim that this is a complex task and that the benefits might not be as great as expected because AOT-generated code would be slower than JIT-generated one, so they implemented a simpler solution in JDK 5, Class Data Sharing. It’s pretty limited because it only works with the Client VM and the serial garbage collector and also because it only loads a set of classes from the system jar.
Interestingly, IBM did some work in this area in the IBM JRE for Java 5 and improved it further in the one for Java 6. This is described in some detail in a developerWorks article. It’s worth reading if you’re interested in this sort of thing, but I’ll list some points that I found interesting:
- AOT code can be stored into a shared class cache allowing another JVM to use it to reduce startup time.
- Class compression is used to increase the amount of classes that are stored in the cache.
- AOT code is also subject to JIT compilation if it’s invoked often in order to optimise it further.
- AOT code executed by a JVM is copied from the shared class cache so there is no direct footprint benefit but there are memory and CPU savings from being able to reuse this code rather than repeat the compilation.
- AOT compilation is based on heuristics that select methods that are likely to improve startup time.
- Eclipse without any additional plugins took 3.313 to start with AOT and shared classes versus 4.204 seconds without. Larger improvements could take place if there were more plugins installed.
- Tomcat startup time improved from 1138ms to 851ms. Using shared classes without AOT caused the time to be 950ms, which means that both AOT and shared classes contributed to the improvement.
Downloading the IBM JRE/JDK requires registration and in case you need the Windows version, you must download a bundle that includes Eclipse. Links to the various downloads can be found in the developerWorks article.
These are interesting results, and it would be interesting to find out if HotSpot would also benefit from similar enhancements.
Regarding IBM results: Tomcat startup time is irrelevant for web app users and, to a large extent, web app developers, because they normally do not need to restart Tomcat itself on a regular basis.
That said, startup time can indeed make a difference for users of desktop apps, e.g. Eclipse RCP. You may find Eclipse Classic compiled with the latest Excelsior JET 6.5 beta 2 at the URL under my name. Though we have not worked specifically on the RCP startup time yet, it seems to launch reasonably fast on our systems.
I agree that the main benefit is for desktop applications, but I think you’re mistaken when you say that web app developers do not restart Tomcat itself on a regular basis. Products like JavaRebel have improved the situation, but for all web developers that still don’t use it, restarting Tomcat is very common given the brittleness of hot deployment and hotswap.
“Tomcat startup time is irrelevant for web app users and, to a large extent, web app developers,” – not true. Any restart gives a load hit: if you have a 200 request/second server, then the longer it restarts, the more the chance it won’t start it all, instead crumbling under the load. There is a noticable difference between how easy it is to restart for an AOT C++ server and a similar Java server.
And Tomcat isn’t the best representative for this restart hit, it is merely a layer. If it is a layer over a C++ database, then okay, but if it is a layer over some heavy Java things, like Velocity template parsers and Berkley DB-JE, then the hit is quite large.
Well, I agree that the convenience of developers should be considered, but once your app is in production environment, you should not need to restart the server. If you do find your self restarting it on a regular basis, something is wrong with your app, your config, your hardware, or whatever.
“If you do find your self restarting it on a regular basis, something is wrong with your app, your config, your hardware, or whatever.” – true, for example, I might need to restart it because the JVM run out of perm space or because there is a security hole in the JVM which must be fixed ASAP or because I need to update one of the libraries or for million other reasons. Welcome to real world.