1.
Motivation for creating
Java/Java Virtual Machine?
Java developed to full
fill the need of Platform Independent Programming language. JVM full fills this
by dividing Compilation and Execution.
Compilation: Java compiler
creates binaries(.class file) not related to the Instruction set of Host
Machine .
Execution: Platform
dependent Execution Engine (JVM) interpreted and Executed JVM specific
instruction Set contained in .class file.
Non-Virtual Machine based
compiled Languages(c,c++ etc)

Virtual machine based compiled
Language(Java):
Compilation :
Java Compiler comes with JDK(java
Development Kit) , which compiles the java files(*.java) to binary
files(*.class) containing the java Instruction Set. The binary format is
independent of underlying Hardware and Operating System. Java Compiler also
resolves compile time dependencies while compilation along with that it also
generates boiler plate code to resolve metadata expressions like Annotations
etc.
Boilerplate code: Section of code that have
to be included in many places with little or no alternation.

Execution:

Flavors of JVM:
There are three
major flavors of Java Execution Engine available today:
1.
Interprets
byte-code one Instruction at a time and executes the same.
2.
Recompiles
the .class files (primary Binaries) generated by Java Compiler containing JVM
Instruction Set to Binaries containing HOST system’s Instruction Set and
executes (JIT). Here the recompilation takes place the first time the class is
loaded, the recompiled binaries are cached in the memory and is reused hence
such Java Execution Engine requires more memory to operate upon.
3.
Interprets
byte-code one at a time as well as identifies and Recompiles the most used code
areas to binaries containing HOST Instruction Set. Such adaptive optimization
brings the best of both the worlds with fast execution time and reduced memory
footprint.
Java (JVM) Class Loader:
Class Loader is a component with the java Execution Engine which loads binary
data from the .class file available in the class path into the method Area.
Loading of a class file into method area occurs only at first time when the
class is referenced with the running java application.
For all the other references the data has been
reused unless the class has been unloaded.

Class
Loader Name Space Separation:
When JVM started three class loaders
are used
1. Bootstrap Classloader
2. Extension Classloader
3. System classloader
Bootstrap Classloader
loads the core java libraries located in <JAVA_HOME> /jre/lib directory.
This class loader written in native code.
The
extensions class loader loads the code in the extensions directories (
<JAVA_HOME>/jre/lib/ext, or any other
directory specified by the java.ext.dirs system property). It is implemented by the sun.misc.Launcher$ExtClassLoader class.
The
system class loader loads code found on
java.class.path, which maps to the CLASSPATH environment variable. This is implemented by the sun.misc.Launcher$AppClassLoader class.
Java
class loader written in java.
Each
class Loader has its own namespace , while loading each class JVM keeps track
of which Class Loader loaded the class. When a loaded class references another
class, JVM tries to load the class using the same classloader which loaded the
reference class.
Hence by default
classes loaded by a common Class Loader falls under the same Name Space and are
visible to each other. Classes loaded by different Class Loaders fall into
different Name Space and cannot gain access to each other. Hence one can
enforce user defined security boundary across a given section of a Java
application by using a Custom Class Loader to load classes’ specific to that
section.

Let’s consider there
are multiple Applets running in the same browser and each of them is loading
code from a different source, but all of them are scheduled over the same Java
Run Time or JVM. Under such condition none of the applets will have visibility
of the other (unless explicitly done) as each of them will be loaded using a
different Class Loader and hence will be on a different Name Space.
Parent Child class
Loader Delegation Model:
Every Class Loader
invoked with in the Java Execution Engine has a Parent Class Loader associated
to it except for the ROOT Class Loader known as Boot-Strap Class Loader. While
creating a custom Class Loader we can provide the Parent Class Loader to be
associated with it or go with the one provided by the JVM.
Responsibilities
as per Class Loader hierarchy:
·
The
Boot-Strap Class Loader is responsible for loading Java-API classes.
·
Application
Class Loader is the default Class Loader for a running Java application,
responsible for loading classes in the application classpath. Boot-Strap Class
Loader is the Parent of Application Class Loader.
·
Custom
Class Loader tries to load classes not with in the Host systems application’s
classpath. (Example – Loading classes over the network from a Hosting Server).
Application Class Loader is the Parent of Custom Class Loader. Although
Custom Class Loaders can also be the Parent of other Custom Class Loaders.
Delegation Model:
·
Every time a Class Loader is asked to load a
class, it delegates the request to its Parent Class Loader. If it’s Parent
Class Loader is not the Boot-Strap Class Loader the request is again delegated
to its Grand Parent Class Loader. This mechanism occurs until the request
reaches the Boot-Strap Class Loader. If the Boot-Strap Class Loader succeeds in
loading the class, the class loading activity stops. But if it fails the
request is again delegated to its immediate Child Class Loader, and this
mechanism continues until it reaches the invoking Class Loader or if any of the
intermediate Class Loaders are able to load the required class.
·
·
Whichever Class Loader is able to load the required class in
the delegation model, the loaded class gets into that particular Class Loader’s
Name Space.
·
·
Demonstrating the Parent Child Delegation model of the Class
Loader using three Class Loading scenarios, each specific to a Class Loading
hierarchy:

Java Method
Area:
Method area is defined memory
section in the HEAP, where the class data is stored when the first time a class
is referenced by the Java application and loaded by the class loader.The size
of the method area is not fixed.
As the java application runs ,the
JVM can expand and contract the Method area to fit the application’s need. The
memory of the method area need not be contiguous . The method are is shared
among all JVM threads. The memory allocated for an Object usually includes some
kind of pointer into the method area for that object to access its class data.
The method area loads the following
class data of the loaded TYPE:
·
The
fully qualified name of the TYPE.
·
The
fully qualified name of the TYPE’s direct Superclass, unless the type is an
Interface or Class (java.lang.Object), as neither of them have a Superclass.
·
A
flag identifying the TYPE as a Class or an Interface.
·
The
TYPE's modifiers.
·
An
ordered list of the fully qualified names of any direct Super-Interfaces.
·
The
Constant Pool for that TYPE.
·
Field
information.
·
Method
information:
o
The
Method's name.
o
The
Method's return type or void.
o
The
number and types (in order) of the Method's parameters.
o
The
Method's modifiers.
o
Method
Data.
·
Static
variable contents of the Method.
·
A
reference to the Class Loader which loaded the Method.
·
A
reference to class Class.
·
Method
Table (A method table is an array of direct references to all the instance
methods that may be invoked on a class instance, including instance methods
inherited from Super-Classes).
JVM STACK:
Every Thread scheduled over the JVM
is provided with a unique Java Stack specific to that Thread. Multiple Threads
running under the same JVM don’t have access to each other’s Java Stack. Java
Stack behaves as LIFO (Last In Fast Out).Threads only share the Heap Space with
other Threads. The JVM performs only two operations over the Java Stack.
1.
Push
Stack Frames.
2.
Pop
Stack Frames
Stack Frames
Each Method of a Class gets its own Stack Frame. Each time a Method is executed by a Java Thread that Method’s Stack Frame is PUSHED in to the TOP of Java Stack of that particular Thread. Once the Thread completes the execution of the Method (or an Exception occurs and is not caught with in that Method’s body), its Stack Frame is POPED out of the Java Stack of that particular Thread and is discarded.
Stack Frame holds the following:
·
Local
Variables: The local variables section
contains a method's parameters and local variables. Compilers place the
parameters into the local variable array first, in the order in which they are
declared. Instance Method's also have a hidden 'this' reference passed along
with its parameters.
·
Operand
Stack: It's like virtual registers, where
values from the local variables are PUSHED into the operand stack, the
instructions POPS those values from the operand stack works on them and then
PUSHES back the result. The Result again gets POPED out of the operand stack
and gets stored into the local variables.
·
Frame
Data: includes data to support constant
pool resolution, normal method return, and exception dispatch.
While
running the below program, the following activities occurred over the Java
Stack.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Check {
public
void InnerMethod()
{
System.out.println("
Executing Inner Method ");
}
public
void OuterMethod()
{
System.out.println("
Executing Outer Method ");
System.out.println("
Outer Method: About to call Inner Method ");
InnerMethod();
System.out.println("
Outer Method: Call to Inner Method returned ");
}
/**
*
@param args
*/
public
static void main(String[] args) {
//
TODO Auto-generated method stub
Check
check = new Check();
check.OuterMethod();
}
}
|
1.
As
the program starts’ executing the Stack Frame of the ‘main’ Method is PUSHED
into the Java Stack of the running thread.
2.
As
the ‘OuterMethod’ is called from with the ‘main’ Method, the OuterMethod’s
Stack Frame is PUSHED into the Java Stack of the running thread.
3.
As
the ‘InnerMethod’ is called from with the ‘OuterMethod’ Method, the InnerMethod’s
Stack Frame is PUSHED into the Java Stack of the running thread.
4.
As
‘InnerMethod’ completes execution its Stack Frame is POPPED out of the Stack
Frame.
5.
As
‘OuterMethod’ completes execution its Stack Frame is POPPED out of the Stack
Frame.
6.
As
‘main’ completes execution its Stack Frame is POPPED out of the Stack Frame.
JVM INTERNAL STRUCTURE:
1.
First time when a Class is referenced by a Java Application, the Class Loader loads the Class in the Method Area.
First time when a Class is referenced by a Java Application, the Class Loader loads the Class in the Method Area.
2.
Every
Java Thread runs on a separate Java Stack provided by the JVM.
3.
Every
Java Thread has a separate Program Counter (PC) which stores a native pointer
and a return address. PC holds the address of the current Instruction being
executed by the Thread.
4.
Stack
Frames are PUSH and POP out of the Java Stack during call to a Method and
return from a Method.
5.
The
Java Heap is divided into:
o
Young
Generation – This is where all new objects are allocated and aged.
o
Old
Generation – This is used to store long surviving objects.
o
Permanent
Generation – This contains META data required by JVM (holds the Method Area and String Pool)
Java Garbage Collection:
JVM runs a GC Demon
Thread which periodically frees up memory occupied by non-referenced objects in
the Heap. An object is eligible for Garbage Collection if there are no live
references of that Object. The behavior of Garbage Collection in JVM differs
between different sections of Heap. The Heap is primarily divided into 3
sections:
1.
Young
Generation – This is where all new objects are allocated and aged. When the
young generation fills up, this causes a minor garbage collection. Some
surviving objects are aged and eventually moved to the old generation.
2.
Old
Generation – This is used to store long surviving objects. Typically, a
threshold is set for young generation object and when that age is met, the
object gets moved to the old generation. Eventually the old generation needs to
be collected. This event is called a major garbage collection.
3.
Permanent
generation – This contains metadata required by the JVM to describe the classes
and methods used in the application. It contains the Method Area and String
Pool Area. The permanent generation is included in a full garbage collection.
**
Major GC is slower than the Minor GC because Major GC involves live Objects.
Object
Allocation, Ageing and Garbage Collection
New
objects are allocated to the eden space. Both survivor spaces start out empty.
When the
eden space fills up, a minor garbage collection is triggered.
Surviving
objects from eden space are moved to the first survivor space. Unreferenced
objects are deleted when minor garbage collection is triggered in eden space.
At the
next minor GC, surviving objects from eden space are moved to the second
survivor space along with that Objects from first survivor space are aged and
moved to second survivor space. Once all surviving objects have been moved to
second survivor space, both first survivor space and eden are cleared
At the
next minor GC, the same process repeats. However this time the survivor spaces
switch. Referenced objects are moved to first survivor space. Surviving objects
are aged. Eden and second survivor space are cleared.
At the
next minor GC, aged objects which has reached a certain Threshold are moved to
Old Generation
As minor
GCs continue to occure objects will continue to be promoted to the old
generation space.
Eventually,
a major GC will be performed on the old generation which cleans up and compacts
that space.
Doubts:
Is
garbage collection works in permanent Generation?
what exactly is the JVM? -- Ans:
·
JVM is a virtual platform that resides on your RAM
·
Its component, Class loader loads
the .class file into the RAM
·
The Byte code Verifier component
in JVM checks if there are any access restriction violations in your code.
(This is one of the principle reasons why java is secure)
·
Next, the Execution Engine component
converts the Bytecode into executable machine code
Optimization:
To
configure a device or application so that it performs better. For example, to
fine-tune a program so that it runs more quickly or takes up less space.
Machine Code
Java combines
the two strategies of compilation and interpretation, as depicted in Figure 3.
Source code is
compiled to JVM bytecode. This bytecode can immediately be interpreted by the
JVM
interpreter. The
interpreter also monitors how much each piece of bytecode is executed (run-time
profiling)
and hands off
frequently executed code (the hot spots) to the just-in-time (JIT) compiler.
The JIT compiler
converts the
bytecode into corresponding machine code to be used instead. Because the JIT
knows what
code is
frequently executed, and which classes are actually loaded into the current
JVM, it can optimize
code in ways
that an ordinary offline compiler could not. It generates reasonably good code
even though it
does not include
some (expensive) optimizations and even though the Java compiler generates
bytecode in
a
straightforward way.
The Java
architecture thus allows code to run on any machine to which the JVM
interpreter has been
ported and to
run fast on any machine for which the JIT interpreter has also been designed to
target. Serious
code optimization effort is reserved for the hot spots in the code.
JVM is basically a stack - based machine.
Class Loader subsystem - a mechanism for loading classes and
interfaces.
When JVM runs a program it needs memory to store many things from
loaded classes
i.e. objects, parameters to methods, return values, local
variables,
methods etc hence runtime data areas are divided into 5 categories
Method area - It is used for storing binary data extracted from
the
loaded classes. The byte code and access types of the methods of
the class,
static variables of the class (their values and access types) are
stored here.
Heap - Java objects exists. Whenever ‘new’ operator is
invoked
the necessary memory is allocated in heap. This space will hold
the
instance variables for the object, pointer to the location of the
object’s class in the method area.
Java Stacks - Java methods are executed. Each method is
executed on a separate frame.
PC registers - shows the memory address of the next instruction to
be executed.
Native Method Stacks - native methods are executed.

Execution Engine - it contains interpreter & Just in time
(JIT) compiler
which converts the byte code into the machine code so that the
processor
will execute it and display results.
JIT Compiler - A JIT is a code generator that converts Java byte
code
into native machine code. Java programs invoked with a JIT
generally
run much faster than when the byte code is executed by the
interpreter.
JIT -
Just In Time Compiler
- Java
virtual machine(JVM) handles only one bytecode instruction
at a time that makes execution slow. But Using the Java just-in-time(JIT)
compiler at the particular system platform compiles the bytecode into the
particular system code. After the code has been (re-)compiled by the JIT
compiler, it will usually run more quickly on the computer.
- The just-in-time compiler comes with JVM and
is used optionally.
- JIT compiles the bytecode into
platform-specific executable code that is immediately executed.
- JIT
compiler option should be used especially if
the method executable is repeatedly reused in the code.
Interpreter Vs JIT Compiler
The interpreter basically does this
§ Read the next byte code to be executed
§ Look at what the byte code is and find the native machine
§ instruction(s) that correspond to it
§ Execute the native machine instruction(s)
§ Go to step 1
That is simple, it works well, and it will run your Java program.
But it's also inefficient, because looking up the native
instruction(s)
for every single byte code to be executed costs processing time.
So the JVM contains a second mechanism, the Just-In-Time compiler,
which basically does this
§ Read all the byte codes for the method that needs to be executed
§ Convert all those byte codes to native machine instructions
§ Execute the generated native machine instructions.
After it has converted the byte codes for a method to native
machine instructions, the JVM remembers that native code, so that
the next time the method has to be run, it can simply run the
native instructions - it doesn't need to convert the byte codes
every time the method is run. This makes the program run much
faster.
Also, the JIT performs lots of optimizations to generate native
code that runs as fast as possible.
JIT -
Just In Time Compiler
- Java
virtual machine(JVM) handles only one bytecode instruction
at a time that makes execution slow. But Using the Java just-in-time(JIT)
compiler at the particular system platform compiles the bytecode into the
particular system code. After the code has been (re-)compiled by the JIT
compiler, it will usually run more quickly on the computer.
- The just-in-time compiler comes with JVM and
is used optionally.
- JIT compiles the bytecode into
platform-specific executable code that is immediately executed.
- JIT
compiler option should be used especially if
the method executable is repeatedly reused in the code.
Interpreter Vs JIT Compiler
The interpreter basically does this
Read the next byte code to be executed
Look at what the byte code is and find the native machine
instruction(s) that correspond to it
§ Execute the native machine instruction(s)
§ Go to step 1
That is simple, it works well, and it will run your Java program.
But it's also inefficient, because looking up the native
instruction(s)
for every single byte code to be executed costs processing time.
So the JVM contains a second mechanism, the Just-In-Time compiler,
which basically does this
§ Read all the byte codes for the method that needs to be executed
§ Convert all those byte codes to native machine instructions
§ Execute the generated native machine instructions
After it has converted the byte codes for a method to native
machine instructions, the JVM remembers that native code, so that
the next time the method has to be run, it can simply run the
native instructions - it doesn't need to convert the byte codes
every time the method is run. This makes the program run much
faster.
Also, the JIT performs lots of optimizations to generate native
code that runs as fast as possible.
Class Loading
and Unloading:
Class Loader
is one of the major component or sub system of the Java Virtual Machine. This
posts talks about loading and unloading of a class (or interface) into virtual
machine. JVM specification refers to classes and interfaces as type.
A Java program is composed of many individual class files, unlike C/C++ which has single executable file. Each of these individual class files correspond to a single Java class and it gets loaded the first time you create an object from the class or the first time you access a static component (block, field or method) of the class.
A class loader's basic objective is to service a request for a class. JVM needs a class (ofcourse for instnating it), so it asks the class loader by passing name of the class. And in return class loader gives back a Class object representing the class. Below diagram shows sequence of steps before loading a class as well as after class gets loaded. Please note sequence of steps from (1) to (6).
A Java program is composed of many individual class files, unlike C/C++ which has single executable file. Each of these individual class files correspond to a single Java class and it gets loaded the first time you create an object from the class or the first time you access a static component (block, field or method) of the class.
A class loader's basic objective is to service a request for a class. JVM needs a class (ofcourse for instnating it), so it asks the class loader by passing name of the class. And in return class loader gives back a Class object representing the class. Below diagram shows sequence of steps before loading a class as well as after class gets loaded. Please note sequence of steps from (1) to (6).
What is Java
Runtime Environment (JRE)
§ The Java
Runtime Environment (JRE)
consists of the Java Virtual Machine, the Java libraries, and all other
components necessary to run Java applications.
i.e. JRE = JVM + Java Packages Classes(like util, math, lang, awt,swing etc)+runtime libraries.
i.e. JRE = JVM + Java Packages Classes(like util, math, lang, awt,swing etc)+runtime libraries.
What is JDK - Java Devleopment Kit
§ The "JDK" is the Java Development Kit. I.e., the JDK is bundle
§ of software that you can use to develop Java based software.
§
§ Typically, each JDK contains one (or more) JRE's along with the
§ various development tools like the Java source compilers,
§ bundling and deployment tools, debuggers, development libraries, etc.
§
§ Primary components are like...
§
§ java - the loader for Java applications. This tool is an interpreter
§ and can interpret the class files generated by the javac compiler.
§
§ javac - the compiler, which converts source code into Java bytecode
§
§ appletviewer - this tool can be used to run and debug Java applets
§ without a web browser
§
§ javadoc - the documentation generator, which automatically generates
§ documentation from source code comments
§
§ jar - the archiver, which packages related class libraries into a
§ single JAR file. This tool also helps manage JAR files.
§
§ javah - the C header and stub generator, used to write native methods
§
§ etc...
§
§ What is SDK - Software
Devleopment Kit
§
§
§ The JDK is a subset of what is loosely defined as a software development kit (SDK)
§ in the general sense. In the descriptions which accompany their recent releases
§ forJava SE, EE, and ME, Sun acknowledge that under their terminology, the JDK
§ forms the subset of the SDK which is responsible for the writing and running of
§ Java programs.The remainder of the SDK is composed of extra software, such as
Application Servers,Debuggers, and Documentation.
Class Loading
In
the JVM architecture tutorial (link),
I have discussed class loader sub system briefly. JVM has a flexible class loader
architecture that enables a Java application to load classes in custom ways.
Each JVM has at
least
two class loaders. Let's cover both of them :
·
Bootstrap class loader :
This is part of JVM implementation and used to load the Java API classes only.
So this class loader "bootstraps" the JVM. Bootstrap class
loader is also known as primordial, system or default class loader.
·
User-defined class loaders
: There could be multiple user-defined class loaders. These are just like
normal Java objects so application can install user-defined class loaders to
load classes in custom way. So using user-defined class loaders you can
dynamically extend Java application at run time. A Java application can
instantiate multiple user-defined class loaders.
JVM keeps track of which class loader
loaded a given class. JVM also keeps in mind security aspect, by default,
classes can only see other classes loaded by the same class loader. Java
architecture achieves this by maintaining name-space inside a Java application.
Each class loader in a running Java application has its own name-space and
class inside one class loader can't access a class from another class loader
unless the application explicitly permits this access. This name-space
restriction means :
·
You can load only ONE class
named as Fruit in a given name-space.
·
But you can create multiple
name-space by creating multiple class loaders in the same application. So you
can load three Fruit classes in three different class
loaders. And all these Fruit classes will be unaware of the presence of rest
two.
Now
obvious question is, how these multiple class loaders in the same application
load classes ?
Class loaders use Parent-delegation technique to load classes. Each class
loader except bootstrap class loader has a parent. Class loaders asks its
parent to load a particular class. This delegation continues all the way to the
bootstrap class loader, which is the last class loader in the chain. If the
parent class loader can load a type, the class loader returns that type. Otherwise
current class loader attempts to load the class itself. This approach ensures
that you can't load your own String class, because request to load a new
String class will always lead to the System/bootstrap class loader which is
responsible for loading Java API classes. Also classes from Java API get loaded
only when there is a request for one.
What
if I create my own class in Java.util package ?
Java gives special privileges to classes in the same package. So
does it mean my class say Jerk inside Java.utilpackage
will get special access and security will get compromised ?
Java only grants this special access to class in the same
package which gets loaded by the same class loader. So your Jerk class which
would have got loaded by an user-class loader will NOT get access to java.lang classes of Java API. So code found on
class path by the class path class loader can't gain access to package-visible
members of the Java API.
Class Unloading
Lifetime of a class is similar to the lifetime of an object. As
JVM may garbage collects the objects after they are no longer referenced by the
program. Similarly virtual machine can optionally unload the classes after they
are no longer referenced by the program.
Java program can be dynamically extended at run time by loading
new types through user-defined class loaders. All these loaded types occupy
space in the method area. So just like normal heaps the memory footprints of
method areas grows and hence types can be freed as well by unloading if they
are no longer needed. So just like normal heap memory if the application has no
references to a given type, then the type can be unloaded or garbage
collected.
Types
(Class/Interface) loaded through the bootstrap loader will always be reachable
and will never be unloaded. Only
types which are loaded by user-defined class loaders can become unreachable and
hence can be unloaded by JVM. A class instance can be reachable in following
case :
·
Class instance will be
reachable if the application holds an explicit reference reference to the
instance.
·
Class instance will be
reachable if there is a reachable object on the heap whose type data in the
method area refers to the Class instance.
Author: Sahitya Mittapalli












No comments:
Post a Comment