Analysis of the operation principle of java program

Analysis of the operation principle of java program

class file content

The content of the class file contains the bytecode executed by the java program , and the data is arranged in a binary stream in the class file in strict accordance with the format, without any separator in the middle; there is a special flag of 0xcafebabe (hexadecimal) at the beginning of the file .

JVM runtime data area

The final execution of the java program is some adaptations made by the JVM execution engine and the local library , so the execution engine and the local library on linux and windos will be different , the purpose is to write once and run everywhere . If you want to use the JVM For in-depth research, you can look at the C code, such as openjdk

Thread exclusive: each thread will have its own independent space, which is created and destroyed with the life cycle of the thread

Thread sharing: All threads can access this memory data, which is created and destroyed with the virtual machine or GC

Method area

JVM is used to store loaded class information, constants, static variables, compiled code and other data . This is a logical area in the virtual machine specification . The specific implementation is based on different virtual machines. As the oracle HotSpot in place permanently region generation method as Java7 , java8 on metadata space and by managing the mechanism of the GC area . For example, IBM's virtual machine implementation is different

heap

Heap memory can also be subdivided into: old generation, new generation (Eden, From Survivor, To Survivor) . JVM is created when it starts and stores the instance of the object . Refuse rubbish collector is mainly managed heap memory . If it is full, OutOfMemoryError will appear

Virtual machine stack

Each thread has a private space in this space . The program stack is composed of multiple stack frames . A thread will execute one or more methods, and a method corresponds to a stack frame .

The contents of the stack frame include: local variable table , operand stack , dynamic link , method return address , additional information, etc.

The maximum stack memory is 1M by default, and StackOverflowError will be thrown if it exceeds

Native method stack

And virtual machine stack function is similar , VM stack for the implementation of java Virtual Machine prepared, native method stacks is to use native native methods for virtual machines prepared , virtual machine stack specification does not provide specific implementations by different virtual The implementation of the machine manufacturer. The implementation of the virtual machine stack and the local method stack in the HotSpot virtual machine is the same. The StackOverflowError will also run out after the size is exceeded

Program counter

Record the current thread executes bytecode location , storing the address of the bytecode instructions , if executed Native method, the counter value is null .

Each thread has a private space in this space, which takes up very little memory .

The CPU can only execute instructions in one thread at the same time . JVM multi-threading will alternately switch and allocate CPU execution time . In order to know the specific execution position after thread switching , the program counter needs to be used to restore the correct execution position

Practical analysis

java file example

public class Demo {
    
    public static void main(String[] args) {
        int a = 1000;
        int b = 100;
        int c = a/b;
        int d = 13;
        System.out.println(c + d);
    }
}
 
javac Demo.java //java class 
javap -v Demo.class > Demo.txt //class txt 
 

Analyze script files

public class com.Demo
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #5.#25        //java/lang/Object."<init>":()V
   #2 = Fieldref           #26.#27       //java/lang/System.out:Ljava/io/PrintStream;
   #3 = Methodref          #28.#29       //java/io/PrintStream.println:(I)V
   #4 = Class              #30           //com/Demo
   #5 = Class              #31           //java/lang/Object
   #6 = Utf8               <init>
   #7 = Utf8               ()V
   #8 = Utf8               Code
   #9 = Utf8               LineNumberTable
  #10 = Utf8               LocalVariableTable
  #11 = Utf8               this
  #12 = Utf8               Lcom/Demo;
  #13 = Utf8               main
  #14 = Utf8               ([Ljava/lang/String;)V
  #15 = Utf8               args
  #16 = Utf8               [Ljava/lang/String;
  #17 = Utf8               a
  #18 = Utf8               I
  #19 = Utf8               b
  #20 = Utf8               c
  #21 = Utf8               d
  #22 = Utf8               MethodParameters
  #23 = Utf8               SourceFile
  #24 = Utf8               Demo.java
  #25 = NameAndType        #6:#7         //"<init>":()V
  #26 = Class              #32           //java/lang/System
  #27 = NameAndType        #33:#34       //out:Ljava/io/PrintStream;
  #28 = Class              #35           //java/io/PrintStream
  #29 = NameAndType        #36:#37       //println:(I)V
  #30 = Utf8               com/Demo
  #31 = Utf8               java/lang/Object
  #32 = Utf8               java/lang/System
  #33 = Utf8               out
  #34 = Utf8               Ljava/io/PrintStream;
  #35 = Utf8               java/io/PrintStream
  #36 = Utf8               println
  #37 = Utf8               (I)V
{
  public com.Demo();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                 //Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 8: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/Demo;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=5, args_size=1
         0: sipush        1000
         3: istore_1
         4: bipush        100
         6: istore_2
         7: iload_1
         8: iload_2
         9: idiv
        10: istore_3
        11: bipush        13
        13: istore        4
        15: getstatic     #2                 //Field java/lang/System.out:Ljava/io/PrintStream;
        18: iload_3
        19: iload         4
        21: iadd
        22: invokevirtual #3                 //Method java/io/PrintStream.println:(I)V
        25: return
      LineNumberTable:
        line 11: 0
        line 12: 4
        line 13: 7
        line 14: 11
        line 15: 15
        line 16: 25
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      26     0  args   [Ljava/lang/String;
            4      22     1     a   I
            7      19     2     b   I
           11      15     3     c   I
           15      11     4     d   I
    MethodParameters:
      Name                           Flags
      args
}
SourceFile: "Demo.java"
 

Version access flag description

 minor version: 0 // 
 major version: 52 //  Java  6,7,8,9   49,50,51,52 >  java8
 flags: ACC_PUBLIC, ACC_SUPER // 
 
Logo name Flag value meaning
ACC_PUBLIC 0x0001 Is it a public type
ACC_FINAL 0x0010 Whether it is declared final, only the class can be set
ACC_SUPER 0x0020 Whether to allow the use of invokespecial bytecode instructions, this flag is true for classes compiled after JDK1.2
ACC_INTERFACE 0X0200 Mark this is an interface
ACC_ABSTRACT 0X0400 Whether it is an abstract type, this flag is true for interfaces and abstract classes, and the others are false
ACC_SYNTHETIC 0X1000 This class is not generated by the user
ACC_ANNOTATION 0X2000 Identifies that this is an annotation
ACC_ENUM 0x4000 Identifies that this is an enum

Static pool description

There is a certain difference between this constant pool and the String constant pool. The static pool here stores some static constants contained in the class, such as the name of the class, the name of the method, the name of the variable declaration, and other information. It can be confirmed after compiling this class.

Constant pool:
   #1 = Methodref          #5.#25        //java/lang/Object."<init>":()V
   #2 = Fieldref           #26.#27       //java/lang/System.out:Ljava/io/PrintStream;
   #3 = Methodref          #28.#29       //java/io/PrintStream.println:(I)V
   #4 = Class              #30           //com/Demo
   #5 = Class              #31           //java/lang/Object
   #6 = Utf8               <init>
   #7 = Utf8               ()V
   #8 = Utf8               Code
   #9 = Utf8               LineNumberTable
  #10 = Utf8               LocalVariableTable
  #11 = Utf8               this
  #12 = Utf8               Lcom/Demo;
  #13 = Utf8               main
  #14 = Utf8               ([Ljava/lang/String;)V
  #15 = Utf8               args
  #16 = Utf8               [Ljava/lang/String;
  #17 = Utf8               a
  #18 = Utf8               I
  #19 = Utf8               b
  #20 = Utf8               c
  #21 = Utf8               d
  #22 = Utf8               MethodParameters
  #23 = Utf8               SourceFile
  #24 = Utf8               Demo.java
  #25 = NameAndType        #6:#7         //"<init>":()V
  #26 = Class              #32           //java/lang/System
  #27 = NameAndType        #33:#34       //out:Ljava/io/PrintStream;
  #28 = Class              #35           //java/io/PrintStream
  #29 = NameAndType        #36:#37       //println:(I)V
  #30 = Utf8               com/Demo
  #31 = Utf8               java/lang/Object
  #32 = Utf8               java/lang/System
  #33 = Utf8               out
  #34 = Utf8               Ljava/io/PrintStream;
  #35 = Utf8               java/io/PrintStream
  #36 = Utf8               println
  #37 = Utf8               (I)V
 
Constant name meaning
CONSTANT_utf8_info UFU8 encoded string
CONSTANT_Integer_info Shaping literal
CONSTANT_Float_info Floating-point literal
CONSTANT_Long_info Long literal
CONSTANT_Double_info Double-precision floating-point literal
CONSTANT_Class_info Symbolic references to classes or interfaces
CONSTANT_String_info String type literal
CONSTANT_Fielderf_info Symbolic references for fields
CONSTANT_Methodref_info Symbolic references to methods in the class
CONSTANT_InterfaceMethodref_info Symbolic references to methods in the interface
CONSTANT_NameAndType_info Symbolic references to fields or methods
CONSTANT_MothodType_info Flag method type
CONSTANT_MothodHandle_info Represents the method handle
CONSTANT_InvokeDynamic_info Represents a dynamic method call point

Default constructor

 public com.Demo();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                 //Method java/lang/Object."<init>":()V
         4: return
 

It can be seen that when the constructor is not defined, there will be an implicit public no-argument constructor

Program entry main method

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC// 
    Code:
      stack=3, locals=5, args_size=1//1  2  3 
         0: sipush        1000 //1000 
         3: istore_1		   //1000 istore_1
         4: bipush        100	//100 
         6: istore_2			//100 istore_2
         7: iload_1				//1000 
         8: iload_2				//100  1000 
         9: idiv				//1000/100=10, 
        10: istore_3			//10 istore_3
        11: bipush        13   //13 
        13: istore        4		//13 istore
        15: getstatic     #2   //PrintStream 
        18: iload_3				//10 
        19: iload         4		//13  10 
        21: iadd				//10+13=23, 
        22: invokevirtual #3   //PrintStream.println(V) . 									 , , 
        25: return			   	//
 

The JVM execution engine executes the compiled instruction codes of these source codes , javap translates operators , and class stores instruction codes . The previous number is the offset (byte) , and JVM distinguishes different instructions according to this. For details, please refer to the JVM instruction code table

summary

The core logic of JVM operation is sorted out in detail

Runtime data area , the relationship between the stack and the stack frame , performing a logical local variables and operand stack table , introduce the relevant instruction code

The lower-level implementation in the operating principle of JVM has different implementations for different operating systems or processors . This is also the reason why java can realize " write once, run anywhere" .