Introduction It simply seems that a shared Java VM, though countlessly times invoked by developers and users, is just not a priority. Promised lots of times, never released. We could discuss for eons about its real usefulness, different schools exist on the topic, anyway it would be at least comfortable to be able to launch different "programs" inside a single JVM, I mean "natively". Yes, because there always have been different ways to achieve this, though partially, though not having all the features we would expect from a real shared VM, using the existing VMs. There's nothing new in this. When we compile a project from inside an IDE, chances are we are calling the main method of the javac class inside an already active jvm, and we do see the difference. Amongs the many projects devoted to shared vm emulation, I've always been fascinated by Javagroup's Echidna Project (the site doesn't exist anymore it seems, but you can download a copy here). With echidna it is possible to load classes and call their main method with their own classpath and class loader, so technically you can launch different java programs inside a sigle JVM. Basing on Echidna, here at beanizer we've created JDEngine(aka JDE, aka Java Desktop Engine), an open source, freely usable engine/service that allows to easily use echidna's features. But let's go back to Echidna. The approach is simple. To launch a new process inside an existing jvm a new class loader gets created, needed classes/libraries are passed and the main method of the executable class is called. Not too complicated, after all our jvm is multi threading. We'll see later the problems/disadvantages of this approach. For now we can enjoy our "hacked" vm, launching all those little utilities we are addicted to without the need to wait for a new vm startup and saving a lot of memory.
Advantages Avoiding to launch a java VM for every single small utility we need has basically two advantages: - Reduced startup time, because all the time usually needed to start the JVM is saved
- Reduced memory requirements, memory usually allocated by the JVM gets occupied only once
Both these points matter. I know CPUs are every day faster and ram is everyday cheaper, but even today the most frequent complaints I hear about java programs are: "It takes too long to start" and "Too much memory is used for just using two little utilities". And personally, using lots of little precious java programs, I love the pseudo-shared vm approach, particularly for utilities I need to launch a lot of time during a working session.
Disadvantages We are only emulating a shared java virtual machine, and this poses some limitations. First of all, if one of our processes crashes, chances are that the entire vm will, together with all the other processes. Second, even if we use different class loaders for our processes, there's not a real segregation between them and this could lead to security problems. Third, the awt event thread is unique for a vm. Avoiding to explain all the implications of this, it means for instance that if one of the processes opens a modal dialog, this will be modal for the whole vm. Fourth, most programs ends with a System.exit call, which will try to kill the VM. We can intercept this, but sometimes it can create some minor problems. Other limitations are related to those programs that make use of a modified class loader which won't often run in our pseudo-shared vm, and so on.
When to use it Being conscious of the related problems, is there space for a pseudo-shared java vm? Maybe yes, basically for what I've written in the "Advantages" section. Usually little utilities, little to medium sized programs will run smoothly inside one single virtual machine, if they don't use exotic class loaders or other fancy vm hacks.
Hasta la proxima.
|