Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

JavaWorld Daily Brew

Poor man's Multi-VM

 

The most recent demos on my weblog are run as separate applications in the same JVM. In addition to its own F3 interpreter, each individual demo gets its own class loader, thread-group, and AWT event-dispatch thread. This is accomplished by using features also used in the applet plugin. Note that this approach isn't specific to F3, but could be used with any Swing application. You can manually kill the applications (which is implemented in the same way that applets are destroyed when you leave a web page). In addition, it installs a security manager that traps System.exit() and destroys the application context of the application rather than exiting the JVM. Some of the F3 demos may appear to start slowly, but that's due to the overhead of F3 or to the fact that many images are being loaded from the network or file system, and not due to the JVM. Self-contained Swing apps (such as SwingSet2) would start instantaneously.

I was prompted to do this by Gilad Bracha (who unfortunately left Sun recently). Gilad told me that he didn't believe in Java GUI's for two reasons:

  1. Start-up time
  2. Footprint

He mentioned a test they did comparing the SmallTalk Squeak IDE, which started up in about 3 seconds and used about 25M of memory, compared to Netbeans which in this test took a minute to start up and used over 100M. But of course you may not consider this a fair test. So next they simply took a screenshot of the Squeak IDE and then wrote a tiny Java program just to display the screenshot. This second program took 3 seconds to start up and also used about 25M of memory, but in the first case we had a fully-functioning SmallTalk IDE and in the other just a bitmap.

I personally found his arguments undeniable.

I did my own tests where I ran 10 instances of SwingSet2 in separate JVMs versus in the same JVM but with separate application contexts. In the former case total memory use was 540M, in the latter 74M.

As I mentioned this approach isn't specific to F3.

I put a zip file containing the basic code to do this for regular Swing applications here (45kb).

Note: this is just example code to illustrate how you could do this.

The zip file contains the source and compiled code and some windows batch files to build and run it (Java 1.6 required to build, Java 1.5 to run).

There's only one class called JApplication. You call its main method with a class path and class name similar to how you run the java command, e.g.

java com.sun.JApplication -classpath SwingSet2.jar SwingSet2

When you run it the first time it creates a server socket on the local host and listens for subsequent connections. At the same time it creates a new thread group, class loader, and application context and runs the application you specified (i.e in this case SwingSet2). When you run it subsequent times it simply connects to the port and writes the command line argument over the socket. The original then creates a new thread group, class loader, and application context as above and runs it in the address space of the original vm. In addition, writes to System.out and System.err from that thread group are redirected back to the socket so you see the console output of your application as expected. It would also be possible to write a C program or shell script to launch your application (rather than using another JVM).

Finally, if you're using Java 1.6 it adds an icon to the system tray which has a menu to shut down the whole thing and also can display a window listing the running applications and which allows you to kill them manually.

Note that this example code doesn't handle security issues at all.