Chapter 4 Classfile conversion 79
4.4 Split machine
A step towards executing Java on small devices is to split the JVM into one class loader and one interpreter, where the interpreter is located in a Figure 4.13 The class image contains preconverted classes, and all other objects on the heap. The object handles are utilised by some garbage collector algorithms, and the roots contain all the roots that the garbage collector needs to locate all the live objects on the heap.
Basic API class templates
Runtime objects Free Heap
Area is GC-algorithm dependent
little node computer and the class loader resides in a more powerful supervision computer. The interpreter does not need to load, link, or even initialise the classes since those tasks may be performed on the supervi-sor computer. However, a small linking step remains in order to install classes in the node. If the only connection with the node is via the supervi-sor, verification may be omitted in the node. The supervisor is responsible for verifying the code. These networks may be found in industry where many smaller nodes are connected to a supervisor computer, e.g. SCADA [SCADA] (see Figure 4.14).
If the nodes do not contain a necessary class, they require it from the supervisor. It could be possible to throw away not utilised classes and methods to save memory in the node. If they are needed, they are fetched from the supervisor. This procedure would of course lead to significant delays, but in a well-trimmed system, it could be possible to only have the
“control loop code” and the interpreter in the node, which would decrease the memory utilisation significantly.
Since the node is behind a secure supervisor, a number of insecure methods could be applied. Verification could be omitted in the nodes. A specialised instruction set and a specialised interpreter could be designed for a node.
The split machine incurs a different memory model from a homogene-ous JVM, since the applications reside in two different memory spaces.
The following sections examine the memory model and the communica-tion protocol of the supervisor and its nodes.
4.4.1 Memory model
An important reason for splitting the machine is to reduce the memory need of the nodes. It is assumed that the supervisor has a large memory in comparison with the nodes, which could consist of inexpensive single chip systems with simple processors and small memory. To achieve this end, nodes execute an interpreter, and the supervisor takes over the rest, i.e. the class loader.
Only the classes that are utilised are necessary in the nodes. Missing classes can be required from the supervisor. Even parts of classes can be loaded as they are needed, e.g. methods. Unutilised classes and methods could be removed in the nodes. In principle, the nodes can remove all classes and methods because those are requested when they are needed.
Static fields have to be stored in the supervisor before they can be Figure 4.14 The configuration of the split machine places the class loader in the supervisor computer and only the interpreter in the node. The class loader can support many nodes.
removed in the node. The supervisor can contain one implementation of a class even though many nodes are utilising it. However, the static fields are uniquely represented for every node that utilises a class. A node could be represented in the supervisor as a thread with its own working envi-ronment as explained in Figure 3.15.
As objects are sent to the nodes, the references of the objects must be converted by the class loader in the node. It is assumed that the supervi-sor does not know the outlook of the node’s heap. The references therefore must be set by the node.
Other memory issues are to omit the symbols in the node and the field and reference descriptions from every class template. Symbols and field descriptions are only relevant if reflection and dynamic class loading is required. The supervisor could perform those tasks.
The nodes utilise a stripped environment as well as reduced class descriptions, with focus on runtime instead of maintainability. Other opti-misations the split machine enables are that interpreters can be modified to suit the hardware architecture of a specific node, and that the bytecode instruction set can be modified in order to suit the memory-limited envi-ronment of a node. The size of the interpreter could be reduced if some bytecodes that are unnecessary for small systems were omitted.
4.4.2 Communication between supervisor and node
The communication between the supervisor and the node consists of object transfers. The supervisor sends the classes and other objects that are required by or requested of the node. When the node removes classes and objects, due to an almost exhausted memory, their static values are sent to and stored in the supervisor. When these removed classes or stored static objects are required, they are again transferred to the node.
When objects are sent from the supervisor to the node, they have to be linked into the runtime system of the node. The object transmission con-sists of four parts:
1. Locate the reference from where the object will be referred.
2. Create the object.
3. Set its value parts.
4. Set references.
The first point (locate the reference position) assumes that the location can be found in the node — the object containing the reference, for exam-ple, may not reside in the node. To simplify matters, the supervisor restricts the references to keep track on to the templates that are loaded in the node, and not on all the roots in the node. It is difficult for the supervisor to determine all the actual runtime roots in the node. One root is, however, always determinable — the environment reference that con-tains the template tables.
Before a sent object is created in the node, its corresponding class must be present. The supervisor keeps track on all the classes that have been sent to the node, as well as the state of each class (skeleton or fleshy). If the node removes the contents of a class template from the runtime
sys-tem, the supervisor must be informed that the removed class is only rep-resented with a skeleton class. The state of the static fields is also sent from the node to the supervisor for storage. Templates cannot be com-pletely removed since they contain information that is necessary for the garbage collector. As the object is created in the node, the object is linked to the template hierarchy so the object may be exposed to the GC.
After the object has been created, the value parts are sent to the node.
The values are sent directly as a memory image of the object, where all the references are set to null. The supervisor and the node must have an equal object representation. If they differ, the supervisor must adapt the object design to the node. An alternative to the object image is to attach type information together with the values, so that the linker of the node can set the correct attributes that are received from the supervisor.
The last step is to set the references. Only references to existing objects may be set. The supervisor is responsible of keeping track of the objects that are installed in the node, and to keep track of all references in the node that have not been set due to the lack of objects.
An example of how three objects are transferred from the supervisor to the node is described in Figure 4.15. The program declares static fields, attributes, and how the created objects are connected. A static variable (ourHero) refers to an object (captainJava) in the object graph. The object therefore can be reached via the template table and sent to the node. Objects are transferred one at a time. Another object has a refer-ence (sidekick in object captainJava) that cannot be set directly after it has been sent away. The referred object does not yet exist in the node.
The supervisor must remember the references that are not set. After the referred object has been sent, the reference is set.
The internal part of the template hierarchy can also be sent. However, the automatic memory management cannot be activated until a minimal set of templates and objects are in place. The meta meta template and its garbage collector information is essential. The meta templates of the GC-information object also must be in place, together with the GC-informa-tion for the meta templates, in other words, if the GC-informaGC-informa-tion is a byte array, the template of the byte array and the meta array template must also be loaded. When all the templates and the GC-information objects are loaded, the garbage collection may commence.
An optimisation to the communication is an installation of a global ref-erence in the node. It is set by the supervisor and utilised as a cache of the last reference position. The reference position description could be shorter, which increases communication performance.
Another communication modification is to keep the static fields in the node at all times, in order to make the supervisor less complex. The node must in any case inform the supervisor about the skeleton classes.