Java virtual machines (JVMs) are built from a variety of pieces. One is the Java language. Java bytecodes are the machine code for a JVM, and Java compilers are needed to translate from Java source to bytecodes. A garbage collector is a requirement, and there are optional pieces like real-time Java support. Sun Microsystems started the picture, but third-party support is what made Java.
With a JVM, developers can easily implement a conventional stack machine as an interpreter on most processors. Luckily, this is just the starting point for most implementations. Just-in-time (JIT) compilers generate native code that can be comparable to native-code compilers for other programming languages. Other alter- natives are Java accelerators from companies like Nazomi (www.nazomi.com) and InSilicon's (www.insilicon.com) JVXtreme coprocessor, which eliminate the need for JIT.
JVMs now provide the performance and reliability necessary for almost any em-bedded application. Most 32-bit and 64-bit embedded CPUs have sufficient performance and memory to handle a JVM.
The Java Community Process (JCP) brings an air of openness to Java. Its Web site provides access to the specifications. Sun licenses many technologies, but third-party products are available. For more info, go to www.jcp.org.
One strength of Java is its third-party support, not only at the higher levels but also down in the trenches with JVMs. This is especially true for embedded environments.
Companies such as NewMonics, IBM (www.ibm.com), Hewlett-Packard (www.
hp.com), and Insignia have JVMs that account for the needs of embedded developers, including real-time support, small footprints, and sophisticated garbage collectors.
The Real-Time Specification for Java (RTSJ/JSR-000001) from the Real-Time for Java Expert Group (www.rtj.org) has been finalized. A reference implementation is available as a free download from TimeSys (www.timesys.com).
RTSJ has been a long time in coming, and commercial implementations have yet to hit the market. The specification is extensive, and it impacts the JVM because it lets applications control not just scheduling but also resources. Although garbage-collection techniques have improved greatly, having control over memory resources allows an application to fine-tune its response time and provide services on a regular basis.
The late coming of RTSJ has not held back real-time Java, though. In fact, most embedded JVMs, like those from NewMonics and Insignia, handle real-time chores using the underlying real-time operating system (RTOS). JNI often provides access to specialized RTOS support. Designers will be able to use RTSJ in the future.
A JVM can have more than one compiler associated with it. The first compiles Java source code to Java bytecodes. That's it if the JVM executes all bytecodes using an interpreter. Java processors or accelerators execute bytecodes directly, but most JVMs use just-in-time (JIT) compilation and possibly ahead-of-time (AOT) compilation to convert bytecodes to native code. These compilers have significantly improved over the years.
A number of factors come into play, to the point where native-code Java execution is on par with other native-code languages, such as C++. Faster processors and more memory permit more analysis and optimizations to be performed. It means native-code integer opcodes can be used to manipulate integer Java variables for common operations instead of having to check the variable type, which results in higher execution overhead. C++ compilers have had plenty of time to include an extremely long list of optimizations that have improved its execution speed. So, Java's performance improvements are not surprising, given the same list.
Many JVMs have given garbage collection a bad rap. Long-running programs running on a JVM with a simplistic garbage collector often pause the program at inopportune times until the process is complete. For this reason, many developers would not consider Java for embedded applications. But this mode of operation is not a requirement for Java. Actually, garbage collection is a well-researched topic independent of Java.
A number of solutions on the market fortunately allow Java applications to run continuously without pausing due to lack of available memory. NewMonics' (www.newmonics.com) hybrid garbage collector uses a number of techniques, including generational garbage collection and pacing (see "Real-Time Garbage Collection Speeds Embedded Java," May 12, p. 60). Pacing runs the garbage collector as a separate task that is designed to stay ahead of the memory needs of other Java applications.
Insignia's (www.insignia.com) multithreaded garbage collector takes into account power management. If the system can go slower, it might be a good time to collect garbage. The processor can then run at even lower power if the system is idling and does not need to run the garbage collector.