JVM low-level principle learning (1) JVM overview

The underlying principle of JVM

As a Java programmer, it would be a pity if you use Java to deal with business logic every day, without knowing the secrets. Whether it's for interviews, tuning, or to understand the entire java operating system, you should have an understanding of the cornerstone of the java platform-JVM, and know what it is and why. This way of learning knowledge can be transparent. If you learn by rote, it will be like a fish’s memory, forgotten in 7 seconds.

What exactly is JVM?

I think the best way to figure this out is to ask the official website

As shown in the figure below:
JVM official website description
The definition given by the official website is the above-mentioned pile of English. I have a bad English, and only understood the first sentence: "Java virtual machine is the cornerstone of the Java platform". Fortunately, there is a Baidu translation. The meaning of is roughly as follows:

  • JVM is the cornerstone of the java platform. It shields the operating system and hardware, and protects our programs from malicious attacks.
  • JVM is an abstract computer. Like a real computer, it has an instruction set and operates various memory spaces at runtime.
  • The JVM virtual machine knows nothing about the java programming language, it only recognizes a special binary format, the class file format.
  • For safety reasons, JVM imposes strict syntax and structural constraints on the code in class files (so java is a strongly typed language), JVM can run available valid class bytecode files, and JVM is a multilingual platform.

How does JAVA cross operating systems and platforms?

The java program runs on the JVM, and the JVM shields the differences between different operating systems, whether it is window, linux, or other systems, as long as jdk is installed, then java bytecode files can be run

JVM is the basis for the cross-platform Java language (Write Once Run Anywhere)
Cross-platform diagram

The relationship between JVM, JDK, and JRE

From the official website you can find the graphic
Insert picture description here
you can see, the JDK contains the JRE included JVM

JDK 8 is a superset of JRE 8, and contains everything that is in JRE 8, plus tools such as the 
compilers and debuggers necessary for developing applets and applications. JRE 8 provides the 
libraries, the Java Virtual Machine (JVM), and other components to run applets and applications 
written in the Java programming language. Note that the JRE includes components not required by
the Java SE specification, including both standard and non-standard Java components.

Translation:
JDK is one of the largest supersets, (Java Development Kit) is a product for Java developers, is the core of the entire Java, including the Java runtime environment JRE, Java tools and Java basic class library.
Java Runtime Environment (JRE) is a collection of environments necessary to run JAVA programs, including JVM standard implementation and Java core class libraries.
JVM is the Java Virtual Machine (Java Virtual Machine), which is the core part of the entire Java implementation of cross-platform, and can run software programs that comply with the JVM specification.

JVM overview

  • Several stages of java code running
    Insert picture description here

Source file compilation (javac)

The process of Test.java -> Test.class
Lexical analyzer -> Syntax analyzer -> Syntax tree/Abstract syntax tree -> Semantic analyzer -> Annotation abstract syntax tree -> Bytecode generator -> class file.
This is actually the course of compilation principles learned in the university. If you don't want to create your own language, you can understand this content.

Bytecode file analysis (.class file)

Open the bytecode file (Test.class) directly with a text tool, and found that it cannot be opened normally, and garbled characters appear. Normal text files cannot open .class files.
Insert picture description here
So let's change to a tool that can open binary files. I use Sublime
Insert picture description here
to open it this time, but all of them are binary codes. I still don't understand it. Let's go to the official website to find the answer.
Document link: official website link

The format defined by the official specification (The class File Format):

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

Insert picture description here
Let's analyze it together

u4 magic
The magic item supplies the magic number identifying the class file format; it has the value
0xCAFEBABE.

magic提供标识类文件格式它的值是固定的CAFEBABE

Insert picture description here

u2 minor_version, u2 major_version
The values of the minor_version and major_version items are the minor and major version numbers
of this class file

当前class文件的支持的jdk的版本号:minor_version是最小版本 major_version是最高的版本.

Lowest version: 0000 in hexadecimal -> converted to decimal or 0.
Highest version: 0034 in hexadecimal -> converted to decimal is 52

Insert picture description here
Insert picture description here
That is to say, the jdk version number currently supported by this class supports 0 at the minimum and 52 at the maximum, which is jdk1.8.
Continue to look down

u2 constant_pool_count
The value of the constant_pool_count item is equal to the number of entries in the constant_pool 
table plus one. A constant_pool index is considered valid if it is greater than zero and less than 
constant_pool_count, with the exception for constants of type long and double noted in §4.4.5.
常量个数

constant_pool[]
The constant_pool is a table of structures (§4.4) representing various string constants, class and
interface names, field names, and other constants that are referred to within the ClassFile structure
and its substructures. The format of each constant_pool table entry is indicated by its first "tag" byte.

The constant_pool table is indexed from 1 to constant_pool_count - 1.

常量池是一个结构表,他包含字符串常量、类和接口名称、字段名以 及在类文件结构及其子结构中引用的其他常量。 每个常量池中的每一项的格式由其第一个“标记”字节表示。
常数池表的索引是从1开始的所以常数池中常量的个数为 constant_pool_count-1

The constant pool mainly stores two aspects: literal (Literal) and symbolic references (Symbolic References)

字面量:文本字符串,final修饰等 
符号引用:类和接口的全限定名、字段名称和描述符、方法名称和描述

Just go to the document bit by bit, go to Baidu to translate, basically you can understand the entire class file. But this one is too time-consuming, and the other is unnecessary. We can use tools to directly translate into text that we humans can understand

Analyze bytecode with javap tool

This tool is a decompilation tool provided by jdk to view bytecode information and instruction information.
Usage:

javap -v -p Test.class > Test.txt
其中:
-v的意思是:查看字节码结构
-p的意思是:将额外的打印字节码信息

Insert picture description here
Open Test2.txt

Classfile /Users/xuehuichen/codingProjects/ideaProject/test/target/classes/com/xhc/test/Test.class
  Last modified 2020-8-15; size 569 bytes
  MD5 checksum 6a6dfaba43dd01223d04bd027262941f
  Compiled from "Test.java"
public class com.xhc.test.Test
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#21         // java/lang/Object."<init>":()V
   #2 = Fieldref           #22.#23        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #24            // 你真好
   #4 = Methodref          #25.#26        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #27            // com/xhc/test/Test
   #6 = Class              #28            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/xhc/test/Test;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               MethodParameters
  #19 = Utf8               SourceFile
  #20 = Utf8               Test.java
  #21 = NameAndType        #7:#8          // "<init>":()V
  #22 = Class              #29            // java/lang/System
  #23 = NameAndType        #30:#31        // out:Ljava/io/PrintStream;
  #24 = Utf8               你真好
  #25 = Class              #32            // java/io/PrintStream
  #26 = NameAndType        #33:#34        // println:(Ljava/lang/String;)V
  #27 = Utf8               com/xhc/test/Test
  #28 = Utf8               java/lang/Object
  #29 = Utf8               java/lang/System
  #30 = Utf8               out
  #31 = Utf8               Ljava/io/PrintStream;
  #32 = Utf8               java/io/PrintStream
  #33 = Utf8               println
  #34 = Utf8               (Ljava/lang/String;)V
{
  public com.xhc.test.Test();
    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 10: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/xhc/test/Test;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String 你真好
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 12: 0
        line 13: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
    MethodParameters:
      Name                           Flags
      args
}
SourceFile: "Test.java"

This will make it clear. Let's try to parse it ourselves to see if it matches the parsed file.
Insert picture description here
Insert picture description here
Then count u1 down

cafe babe 0000 0034 0023(35-1) 0a(10代表的是CONSTANT_Methodref 方法引用)
00 06(第六行)00 15(第21行)09
0016 0017 0800 180a 0019 001a 0700 1b07
001c 0100 063c 696e 6974 3e01 0003 2829
5601 0004 436f 6465 0100 0f4c 696e 654e
756d 6265 7254 6162 6c65 0100 124c 6f63
616c 5661 7269 6162 6c65 5461 626c 6501
0004 7468 6973 0100 134c 636f 6d2f 7868
632f 7465 7374 2f54 6573 743b 0100 046d
6169 6e01 0016 285b 4c6a 6176 612f 6c61
6e67 2f53 7472 696e 673b 2956 0100 0461
7267 7301 0013 5b4c 6a61 7661 2f6c 616e
672f 5374 7269 6e67 3b01 0010 4d65 7468
6f64 5061 7261 6d65 7465 7273 0100 0a53
6f75 7263 6546 696c 6501 0009 5465 7374
2e6a 6176 610c 0007 0008 0700 1d0c 001e
001f 0100 09e4 bda0 e79c 9fe5 a5bd 0700
200c 0021 0022 0100 1163 6f6d 2f78 6863
2f74 6573 742f 5465 7374 0100 106a 6176
612f 6c61 6e67 2f4f 626a 6563 7401 0010
6a61 7661 2f6c 616e 672f 5379 7374 656d
0100 036f 7574 0100 154c 6a61 7661 2f69
6f2f 5072 696e 7453 7472 6561 6d3b 0100
136a 6176 612f 696f 2f50 7269 6e74 5374
7265 616d 0100 0770 7269 6e74 6c6e 0100
1528 4c6a 6176 612f 6c61 6e67 2f53 7472
696e 673b 2956 0021 0005 0006 0000 0000
0002 0001 0007 0008 0001 0009 0000 002f
0001 0001 0000 0005 2ab7 0001 b100 0000
0200 0a00 0000 0600 0100 0000 0a00 0b00
0000 0c00 0100 0000 0500 0c00 0d00 0000
0900 0e00 0f00 0200 0900 0000 3700 0200
0100 0000 09b2 0002 1203 b600 04b1 0000
0002 000a 0000 000a 0002 0000 000c 0008
000d 000b 0000 000c 0001 0000 0009 0010
0011 0000 0012 0000 0005 0100 1000 0000
0100 1300 0000 0200 14

Then correspond to the file that has just been compiled (note the red box in the figure) to
Insert picture description here
see if these numbers are the numbers just calculated.
So it means that the javap tool is also compared in this way, just like the one we launched.
I am just doing a demonstration here. In fact, any technology is not difficult. If you understand the principle, you don’t need to memorize it, and you know what’s going on.

Learning the underlying principles of JVM (two) loading subsystems

Guess you like

Origin blog.csdn.net/nonage_bread/article/details/108015120