Wednesday, October 4, 2017

[JVM-0] Architecture of JVM

Java and Java Platform

Java has 4 core parts
  0. Language: a programmer uses it to write programs
  1. Class file format: java compiler translates it to byte codes to be executed by jvm
  2. JVM: an application that executes bytecode
  3. API: to interact with host machine

Java platform has 2 parts
  0. API
  1. JVM

A Java program runs on a Java platform.

Java program execution

Here are the steps to run a java program on a Java platform.

0. programmer writes java code

  class Test{
    public static void main(String args[]){
      int i = 0;
      int j = 1;
      for(i = 0; i < 10; i++){
        j = j + 1;
      }
    }
  }

1. Compile and produce byte code
              javac Test.java
bytecode has instruction that is targeted for a virtual architecture, java virtual machine.

javap -c Test.class produces the following output

class Test {
  Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_1
       3: istore_2
       4: iconst_0
       5: istore_1
       6: iload_1
       7: bipush        10
       9: if_icmpge     22
      12: iload_2
      13: iconst_1
      14: iadd
      15: istore_2
      16: iinc          1, 1
      19: goto          6
      22: return
}

2. user starts jvm by the command,
                java Test
Note: a jvm only runs a single application. jvm takes a class file as an agrument. the class file must have the main method with proper signature.

3. jvm loads, interprets the byte code and runs on host system.


Parts of JVM

0. Class loader: locates and imports byte code to jvm's memory.
    a. checks correctness of a type.
    a. on method area, loads byte code, initializes class variables. on heap creates Class object.
    b. links bytecode of method area with Class on heap.

there are two types of class loader
    a. bootstrap class loader: loads java api from installation location. this is part of jvm and written in c++ probably.
    b. user defined class loader: java classes created by user. these are objects in heap.

1. Method area: class loader loads byte code instructions to this place. For each class following information are stored
    a. fully qualified name of the type
    b. super class
    c. is it class or interface?
    d. modifier (public, abstract, final)
    e. constant pool: constants used by this type
        - string, int, float,
        - other classes used by this class (initially it holds only a symbolic link(fully qualified name), later when those classes are loaded to method area and in heap, those symbolic links are replaced by reference to class)
    f. field information (field name, type, modifier)
    g. method information
      0. name
      1. return type
      2. argument info
      3. modifier
      4. bytecode
      5. number of local variables
      6. size of operand stack
      7. exception table
    h.  class variable: all class's get a copy of static-final variable. static non-final are stored method area.
    i. class loader reference: reference to the loader that loaded this class.
    j. method table: instruction memory address for each method's start.

2. Java stack: each thread has separate java stack. only push and pop operations are allowed. contains stack frames for methods. each stack frame holds following information of a method
  a. parameters
  b. local variables
  c. operand stack
  d. return val
  e. return address
  f. exception table


      if an exception occurs and not catch clause found for that instruction, jvm causes the method return abruptly and re-throws the exception to the callers context.
one thread cannot access another thread's java stack.

3. Program counter: each thread gets one entry in the program counter (pc). pc remembers the next instruction to be run for a thread.

4. Heap: objects gets created in this area.

5. Execution engine: Fetches instructions from method area, translates and executes them. instructions acts on the data on java stack and heap. each thread is an execution engine. Interpreted byte code is cached and accessed if necessary.
2 popular techniques
  a. just in time compile: One by one, takes byte code, translates to native code, executes.
  b. adaptive: acts just like jit except as soon as it finds a code that is being used a lot of time(hot spot) it forks a thread. the thread heavily optimizes the code in hotspot and jvm in later time executes those optimized instructions.


6. Native method stack: holds frames for native methods. native methods works on the frame data and data in heap of JVM.

The following picture shows architecture of JVM


The following picture depicts Program counter and Java stack



** Object representation on JVM


** Thread Synchronization
Thread needs object locking and wait-notify mechanism to work.
calling the following methods on an object
  a. lock: a thread can access lock to an object. another thread has to wait to acquire the lock until the first thread unlocks the object.
  b. wait: a thread calls wait on an object. jvm puts the thread to the wait list of the object and makes it sleep. the thread sleeps until another thread calls notify or notify all
  c. notify and notify all: a thread calls this method on an object to notify the threads waiting on the object's wait list.

** Type of java threads
0. non-daemon thread: used by jvm. inital thread that starts a program, garbage collector.
1. daemon thread: created by running program.
As long as a non-daemon thread keeps running, the jvm would not stop unless exit method has not been called.

Atomic operations such as int, char operations makes sure a variable gets a value assigned either by one of the racing threads. if thread_1 tries to assign 0100 and thread_0 tries to assign 1011 to a variable x, it is guaranteed that x will have either 0100 or 1011 not any other values.

** Data types of jvm
a. reference type: holds object reference
b. primitive type: holds int, float. boolean false is stored as 0, any non-zero is stored as true. primitive types has same size and properties in all jvms. they don't depend on the host architecture.

As the jvm starts working, it's class loader loads byte codes to jvm's method area.

No comments:

Post a Comment