Thursday, 25 July 2013

Internals of JVM

What is a JVM:

As per Wiki, A Java virtual machine (JVM) is a virtual machine that can execute Java bytecode. It is the code execution component of the Java platform.

As per Java Lang Spec, The Java Virtual Machine is the cornerstone of the Java platform. It is the component of the technology responsible for its hardware- and operating system-independence, the small size of its compiled code, and its ability to protect users from malicious programs.
The Java Virtual Machine is an abstract computing machine. Like a real computing machine, it has an instruction set and manipulates various memory areas at run time. It is reasonably common to implement a programming language using a virtual machine; the best-known virtual machine may be the P-Code machine of UCSD Pascal.

The first prototype implementation of the Java Virtual Machine, done at Sun Microsystems, Inc., emulated the Java Virtual Machine instruction set in software hosted by a handheld device that resembled a contemporary Personal Digital Assistant (PDA). Oracle's current implementations emulate the Java Virtual Machine on mobile, desktop and server devices, but the Java Virtual Machine does not assume any particular implementation technology, host hardware, or host operating system. It is not inherently interpreted, but can just as well be implemented by compiling its instruction set to that of a silicon CPU. It may also be implemented in microcode or directly in silicon.

The Java Virtual Machine knows nothing of the Java programming language, only of a particular binary format, the class file format. A class file contains Java Virtual Machine instructions (or bytecodes) and a symbol table, as well as other ancillary information.
For the sake of security, the Java Virtual Machine imposes strong syntactic and structural constraints on the code in a class file. However, any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java Virtual Machine. Attracted by a generally available, machine-independent platform, implementors of other languages can turn to the Java Virtual Machine as a delivery vehicle for their languages.

Features of JVM:
  • Providing Run time environment
  • Executing byte codes
  • Memory management
  • Dynamically loads, links and initializes classes and interfaces 

More info:
  • Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation. 
  • Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed. 
  • Initialization of a class or interface consists of executing the class or interface initialization method <clinit>.


Internal Architecture:

I find this is one of the best explanations I have ever come across.

From this web source, the internal architecture of JVM is 



Areas such as Method Area & Heap are created when JVM startup and destroyed when JVM exits and shared among all threads.

Areas such as Java Stacks, PC Register, Native Method Stacks are per thread basis, it will be created when Thread is created and destroyed when Thread exits.





Here you go; this table captures the critical piece of info about each area.
 

What is it all about?
Additional info
Exception conditions associated
Method Area

It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.

The method area is created on virtual machine start-up. Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. T

If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.
Heap:

It is the run-time data area from which memory for all class instances and arrays is allocated.

Heap storage for objects is reclaimed by an automatic storage management system (known as agarbage collector); objects are never explicitly deallocated. 

If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError.
JVM Stack:
It holds local variables and partial results, and plays a part in method invocation and return. It stores Frames


If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws aStackOverflowError.
If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError

PC Register:
 At any point, each Java Virtual Machine thread is executing the code of a single method, namely the current method for that thread. 








If that method is not native, the pc register contains the address of the Java Virtual Machine instruction currently being executed. If the method currently being executed by the thread is native, the value of the Java Virtual Machine's pc register is undefined.

Native Method Stacks:

An implementation of the Java Virtual Machine may use conventional stacks, colloquially called "C stacks," to support native methods (methods written in a language other than the Java programming language).

Native method stacks may also be used by the implementation of an interpreter for the Java Virtual Machine's instruction set in a language such as C. 



If the computation in a thread requires a larger native method stack than is permitted, the Java Virtual Machine throws a StackOverflowError.

If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

Run time Constant Pool:

A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file. It contains several kinds of constants, ranging from numeric literals known at compile-time to method and field references that must be resolved at run-time. 

Each run-time constant pool is allocated from the Java Virtual Machine's method area. The run-time constant pool for a class or interface is constructed when the class or interface is created by the Java Virtual Machine.

When creating a class or interface, if the construction of the run-time constant pool requires more memory than can be made available in the method area of the Java Virtual Machine, the Java Virtual Machine throws an 
OutOfMemoryError.

Detailed information of each area can be found in the following link
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5





I consider Memory is one of the main area that we should focus on, so some details about it.


  • Eden Space: Initial memory allocation space.
  • Survivor Space: Survived Objects from garbage collection of the Eden space.
  • Tenured Generation: Objects that persist longer are moved here.
  • Permanent Generation: used for class definitions and associated metadata. It is further divided into shared-RO, shared-RW (Shall be seen in JCONSOLE -> MEMORY section)
  • Code Cache: Used for compilation and storage of native code.
In terms of Generation:

Eden + Survivor = Young Generation
Tenured             = Old Generation
Perm Gen          = Permanent Generation

More details can be found here in the specification:  
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/managemen/MemoryMXBean.html

Tuning the VM itself is a vast topic, please refer
http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html



Modes:

One important thing to notice when you are running Java apps in your JVM – Check the default setting of VM especially it is Client VM/Server VM and the Mode in which it is running. You can simply run ‘java –version’ to find the same.

[root@fedora151 bin]# java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.8) (fedora-65.1.10.8.fc15-i386)
OpenJDK Client VM (build 20.0-b11, mixed mode)

[root@CHN1 lib]# java –version     
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.4) (rhel-1.41.1.10.4.el6-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)


For an intensive, service side application choose Server VM. More details on this topic can be found in the following links.

Conclusion here is, choose

Server VM:
·         To run server applications.
·         When you need maximum operating speed and more memory available.

Client VM:
·         To run GUI applications (better choice)
·         When you need fast start-up times and less memory available


Sources: Stack Overflow, Wikipedia, Oracle, Artima.