The Java Virtual Machine (JVM) is an abstract computer. JVM speciﬁcations deﬁne some features that every JVM must have. Designers can implement the features in their own way. For example, JVM must be able to execute byte code, however, diﬀerent techniques can be used for its execution. The main task of a JVM is to load class ﬁles and execute the bytecode they contain. JVM contains a class loader and an execution engine.
Class loader is responsible for loading class ﬁles from both the platforms and the Java API. The byte code contained in class ﬁles is executed by the execution engine.A General diagram of JVM is shown below:
An execution engine is not any hardware component, instead implemented as a software. It accepts the byte code and produces native code. Just-in-time Compiler (JIT) is a kind of execution engine.
JIT caches native code generated when the method was invoked for the ﬁrst time. The cached code can be reused next time when the same method is invoked.
Java methods are written in Java language, whereas native methods are written in other languages, such as C, C++ etc. Native methods are the part of platform speciﬁc dynamic linked libraries. Means native methods are platform dependent. When a Java program invokes a native method, the JVM loads the library ﬁle to call the method.
As shown in diagram below:
As mentioned earlier, each JVM has a class loader, which is responsible for loading classes and interfaces. Each JVM also has an execution engine to interpret the classes loaded by class loader. A Java Virtual Machine needs some Runtime Data Areas to store bytecode, objects, method parameters, local variables, return values, intermediate results etc. As general architecture of JVM is shown below:
Method Area Method area is analogous to the storage area for compiled code of a conventional language or to the least segment in OS process. Class loader reads byte code from class ﬁle and sends it to virtual machine. Virtual machine reads information about the type from class ﬁle and stores in method area. Virtual machines stores the following information in method area:
• The fully qualiﬁed name of direct super class.
• The fully qualiﬁed name of the type.
• Whether the type is a class or an interface.
• The modiﬁers of type (ﬁ nal, public, abstract).
• Fully qualiﬁed name of interfaces implemented or extended.
• Field information.
• Static variables information.
• A reference to class loader to keep track of class loader used for loading the type: Bootstrap class loader or user deﬁned class loader.
• A reference to class java.lang.Class: class to load every type. The java.lang.Class provides you a static method: forName(String ClassName), which returns a reference of instance of Object class (universal class) for class-name speciﬁed as parameter, for example:
The above statement creates an object of class java.lang.Class and returns the reference to c, using reference variable c, you can extract full information about the members of class String. Detailed discussion about methods of Class class is not subject of discussion in this chapter, for information, you can google it on internet.
JVM creates a new Java stack for each thread to store thread's state by pushing and poping frames on the stack. As a thread calls a method, JVM creates a frame and pushes it on the stack. A frame has 3 parts:
• Local variables
• Frame data
A method called by thread can be completed by returning is called normal completion. If it completes by throwing an exception, it is called abstract completion. On completion of method in any way JVM pops the frame from stack and the previous frame becomes the current frame. Java stack is depicted in diagram shown as follows:
The heap is the runtime data area, from which memory to all class instances and array is allocated. A running Java virtual machine instance has only one heap that is shared by all running threads. The heap is created on start of virtual machine. The size of heap may be ﬁxed or expanded (up to the availability) according to requirement. The memory allocated to heap need not to be contiguous. The JVM throws an OutOfMemoryError, when availability of memory is less than the requirement. To query about the heap size programmatically, you can use the following methods:
Garbage collection is the process run by JVM at random intervals to reclaim the memory from unreferenced/unreachable objects. To know more about garbage collection goto home page visit: Garbage Collection.
Methods written in languages other than Java programming languages such as C, C++ are called native methods.
When a thread calls a Java method, a new frame is created and is being pushed onto the Java stack. When a thread calls a native method, the thread switches from Java stack to native method stack. The parameters(if any) are pushed on native method stack. If a native method calls back a Java method, the thread leaves the native method stack and enters in Java stack again.
Figure shown below demonstrate switching of a thread from Java stack to native method stack that calls back a Java method switches to Java stack.
Java API is a collection of library classes and interfaces organized in diﬀerent packages. The API is written in Java language and run on the JVM. It is commonly used by the programmers to do their programming tasks.
Java API can be of three types, as listed below:
• Oﬃcial Java core API, which is bundled with JDK setup.
• Optional oﬃcial APIs, which may be downloaded if needed.
• Unoﬃcial APIs, which are third party APIs that may be downloaded from source sites.
The Java API contain libraries for socket programming, multitasking, exception handling, date-time operations, handling a collection of objects, creating graphical user interfaces, database connectivity, handling strings, serialization, etc.