summary
When it comes to the three letters of JVM, what first pops out of your mind? I generally analyze the following three kinds of people:
- The first one: I know the three letters of JVM separately. I don't know what it is
- Second: isn't it a Java virtual machine that runs Java programs
- The third kind: it is divided into heap memory, method area, old age, new generation Barbara, I can tell you for hours
After my daily observation, generally, the first kind of people are the family members of the program apes, the second kind of people are the colleagues of the program apes (non Java colleagues), and the third kind of people are the program apes, and the suitable readers of this article are the third kind of people. I try to lead the program apes to re understand the JVM from another height from different perspectives, Step by step from shallow to deep, and once again make a comprehensive comb of the JVM we know. We not only know that it has heap memory, method area, old age, new generation We should also know its principle and the method of its use. Based on an in-depth understanding of its design principle, it will be more handy to use and tune it.
Next, let me gradually lead you into the world of JVM! In the follow-up, I will take you gradually from shallow to deep understanding of JVM in the form of JVM series articles.
Statement: the following contents are long. Please read them patiently, and you will have a different harvest!
Everything starts from the official website
So what should be the first step in understanding the JVM? Many people know JVM for the first time on Baidu or google. In fact, you were wrong in the first step. I think everything should start from the official website and have a comprehensive understanding from the place where it was born.
Java Platform Standard Edition 8 Documentation
Official website address: docs.oracle.com/javase/8/do...
Reference - > developer guides - > navigate to: docs.oracle.com/javase/8/do...
Tips: take some time and read this passage patiently, and you will have new experience!
Oracle has two products that implement Java Platform Standard Edition (Java SE) 8: Java SE Development Kit (JDK) 8 and Java SE Runtime Environment (JRE) 8.
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.
The following conceptual diagram illustrates the components of Oracle's Java SE products:
Getting Started with the G1 Garbage Collector
Official website address: www.oracle.com/technetwork...
Exploring the JVM Architecture
Hotspot Architecture
The HotSpot JVM possesses an architecture that supports a strong foundation of features and capabilities and supports the ability to realize high performance and massive scalability. For example, the HotSpot JVM JIT compilers generate dynamic optimizations. In other words, they make optimization decisions while the Java application is running and generate high-performing native machine instructions targeted for the underlying system architecture. In addition, through the maturing evolution and continuous engineering of its runtime environment and multithreaded garbage collector, the HotSpot JVM yields high scalability on even the largest available computer systems.
The main components of the JVM include the class loader, the runtime data areas, and the execution engine.
Read and understand (excerpt from above):
Original text:
In other words, they make optimization decisions while the Java application is running and generate high-performing native machine instructions targeted for the underlying system architecture
Translation:
In other words, it can make optimization decisions when Java applications run and generate high-performance local machine instructions for the underlying system architecture.
That is to say, the maximum capability of the JVM is to translate Java programs into local machine instructions that can be recognized and executed by different operating systems for different underlying operating systems, and provide them to the operating system for operation.
The following figure is no stranger to people who know the JVM (compile once and run everywhere):
Source code to class file, and then to bytecode
Let's start with the simplest HelloWorld Java, compile it to get HelloWorld Class file. The above two steps are most clear to every Java program. One is Java at the end of the source file, one is We all know that a java program must be compiled into a bytecode file at the end of class Class bytecode file before the JVM can run. But have you ever thought about this How does the bytecode file at the end of class run and print "Hello World" on the console?
Don't worry. Through the following steps, let me lead you into the world of JVM and re understand the JVM from different angles.
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } } Copy code
View a class file bytecode
Let's start with the JDK command: hexdump - C HelloWorld Class to view the next bytecode.
After entering the above command, output the following contents. Now you must not understand this pile of things. Don't worry. First look at what the official website says and see the following contents.
00000000 ca fe ba be 00 00 00 34 00 22 0a 00 06 00 14 09 |.......4."......| 00000010 00 15 00 16 08 00 17 0a 00 18 00 19 07 00 1a 07 |................| 00000020 00 1b 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29 |.....<init>...()| 00000030 56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e |V...Code...LineN| 00000040 75 6d 62 65 72 54 61 62 6c 65 01 00 12 4c 6f 63 |umberTable...Loc| 00000050 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 01 |alVariableTable.| 00000060 00 04 74 68 69 73 01 00 0c 4c 48 65 6c 6c 6f 57 |..this...LHelloW| 00000070 6f 72 6c 64 3b 01 00 04 6d 61 69 6e 01 00 16 28 |orld;...main...(| 00000080 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 |[Ljava/lang/Stri| 00000090 6e 67 3b 29 56 01 00 04 61 72 67 73 01 00 13 5b |ng;)V...args...[| 000000a0 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e |Ljava/lang/Strin| 000000b0 67 3b 01 00 0a 53 6f 75 72 63 65 46 69 6c 65 01 |g;...SourceFile.| 000000c0 00 0f 48 65 6c 6c 6f 57 6f 72 6c 64 2e 6a 61 76 |..HelloWorld.jav| 000000d0 61 0c 00 07 00 08 07 00 1c 0c 00 1d 00 1e 01 00 |a...............| 000000e0 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64 07 00 1f 0c |.hello world....| 000000f0 00 20 00 21 01 00 0a 48 65 6c 6c 6f 57 6f 72 6c |. .!...HelloWorl| 00000100 64 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 |d...java/lang/Ob| 00000110 6a 65 63 74 01 00 10 6a 61 76 61 2f 6c 61 6e 67 |ject...java/lang| 00000120 2f 53 79 73 74 65 6d 01 00 03 6f 75 74 01 00 15 |/System...out...| 00000130 4c 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 |Ljava/io/PrintSt| 00000140 72 65 61 6d 3b 01 00 13 6a 61 76 61 2f 69 6f 2f |ream;...java/io/| 00000150 50 72 69 6e 74 53 74 72 65 61 6d 01 00 07 70 72 |PrintStream...pr| 00000160 69 6e 74 6c 6e 01 00 15 28 4c 6a 61 76 61 2f 6c |intln...(Ljava/l| 00000170 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56 00 21 00 |ang/String;)V.!.| 00000180 05 00 06 00 00 00 00 00 02 00 01 00 07 00 08 00 |................| 00000190 01 00 09 00 00 00 2f 00 01 00 01 00 00 00 05 2a |....../........*| 000001a0 b7 00 01 b1 00 00 00 02 00 0a 00 00 00 06 00 01 |................| 000001b0 00 00 00 06 00 0b 00 00 00 0c 00 01 00 00 00 05 |................| 000001c0 00 0c 00 0d 00 00 00 09 00 0e 00 0f 00 01 00 09 |................| 000001d0 00 00 00 37 00 02 00 01 00 00 00 09 b2 00 02 12 |...7............| 000001e0 03 b6 00 04 b1 00 00 00 02 00 0a 00 00 00 0a 00 |................| 000001f0 02 00 00 00 08 00 08 00 09 00 0b 00 00 00 0c 00 |................| 00000200 01 00 00 00 09 00 10 00 11 00 00 00 01 00 12 00 |................| 00000210 00 00 02 00 13 |.....| 00000215 Copy code
The ClassFile Structure (bytecode parsing)
See how the official website interprets bytecode files:
Official website address: docs.oracle.com/javase/spec...
A class file consists of a single ClassFile structure:
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]; } Copy code
Interpreting bytecode files
First, u4 magic;
- u4: represents 4 bytes Byte (0x cafebabe). It is a magic number (it has no business meaning, but indicates the type of the file)
Basics:
One byte stores 8-bit unsigned numbers, and the stored values range from 0 to 255. 1111 0000 (1 byte)
1Byte = 8bit
1Byte = 2-bit hexadecimal
4Byte = 0x cafebabe
Therefore, u4 magic, which is 0x cafebabe, is converted to binary: 1100 1010 1111 1110 1011 1010 1011 1110
Second and third, u2 minor_version; u2 major_version; (combined into version number)
- u2 minor_version: represents 2 bytes (0x 00 00) and represents the small version number
- u2 major_version: represents 2 bytes (0x 00 34) and represents the major version number
- The major version number + minor version number are combined to form a version number. 0x 00000034 -- > is converted to decimal: 52 (look up the corresponding table, indicating that the version number is Java SE8)
Fourth, u2 constant_pool_count; Represents a constant quantity
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.
- u2 constant_pool_count: represents 2 bytes (0x 00 22). The converted decimal value is 34. It represents the constant pool. The number of constants is 34-1 = 33
- So what constants are there in this class? Look at the following constant array:
Fifth, cp_info constant_pool[constant_pool_count-1]; Represents an array of constants
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.
- The form of each constant:
The Constant Pool
Java Virtual Machine instructions do not rely on the run-time layout of classes, interfaces, class instances, or arrays. Instead, instructions refer to symbolic information in the constant_pool table.
All constant_pool table entries have the following general format:
cp_info { u1 tag; //Indicates the type of constant u1 info[]; //express: } Copy code
First constant:
- u1 tag: represents 1 byte (0x 0a), converted to decimal value: 10. Find the following corresponding table, indicating that it is a constant of method type
// Method type constant CONSTANT_Methodref_info { u1 tag; u2 class_index; u2 name_and_type_index; } Copy code
Constant number | u1 tag | constant type | Constant content |
---|---|---|---|
#1 | 0x 0a-->10 | CONSTANT_Methodref | u2 class_index: 0x 00 06--> #6 u2 name_and_type_index: 0x 00 14 --> #20 #6.#20 |
Other constant parsing: (such a table can be parsed step by step according to the above method)
Up to now, you must still not understand the use of parsing this pile. Don't worry, look at the following command first.
Constant number | u1 tag | constant type | Constant content |
---|---|---|---|
#1 | 0x 0a-->10 | CONSTANT_Methodref | u2 class_index: 0x 00 06--> #6 u2 name_and_type_index: 0x 00 14 --> #20 #6.#20 |
#2 | 0x 09-->9 | CONSTANT_Fieldref | u2 class_index: 0x 00 15--> #21 u2 name_and_type_index: 0x 00 16-> #22 #21.#22 |
#3 | 0x 08-->8 | CONSTANT_String | u2 string_index: 0x 00 17--> #23 |
#4 | 0x 0a-->10 | CONSTANT_Methodref | u2 class_index: 0x 00 18--> #24 u2 name_and_type_index: 0x 00 19 --> #25 #24.#25 |
... | |||
#33 |
javap disassembly
- Command: javap - V - P - C HelloWorld class > HelloWorld_ javap. Txt (disassemble the HelloWorld bytecode file and write the generated content to HelloWorld_javap.txt)
// The intercepted part is as follows: Classfile /.../HelloWorld.class Last modified 2021-9-28; size 533 bytes MD5 checksum c3ef731e76bb9c516e7840a04a0c71af //<-----------magic Compiled from "HelloWorld.java" public class HelloWorld minor version: 0 major version: 52 //< ------------------ version number flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #6.#20 // java/lang/Object."<init>":()V #2 = Fieldref #21.#22 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #23 // hello world #4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #26 // HelloWorld #6 = Class #27 // java/lang/Object #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable ... #33 ... Copy code
Summary
From the above analysis, we probably know that a java source file needs to be compiled into a class file before the JVM virtual machine can really run the whole process of this code. Next, we will study how the class file is loaded into the JVM and the Java class loading mechanism.