Basic Knowledge-Talking about JVM (see the bytecode file to understand the difference between ++i and i++, use Memory to see how String str = "11" produces two OOPs)

1. How a class is loaded

Insert picture description here

.1.1 java file javac will be compiled into a bytecode instruction set file, javap -c Test.class can see the relevant bytecode instructions.
1.2 The class loading subsystem will parse the class file into InstanceKlass metadata and put it in the method area.
1.3 After JDK8, the old generation metaspace is cancelled and replaced by the old generation
1.4 The method area can be understood as the interface old generation metaspace is to implement
1.5 methods The area heap is a shared memory area. The method area mainly contains class metadata, constant pool, static variables, etc., objects are stored in the heap, and local method stacks are extended local methods. The virtual machine stack is a stack frame. A method is a stack frame that is executed and generated Release after execution

2. Virtual machine stack operation ++i and i++

2.1 Let’s take a look at what’s inside the virtual machine stack.
Insert picture description here
2.11 Local variable table: Mainly store the parameter data, local variable data.
2.12 Operand stack: LIFO last-in, first-out stack. During method execution, there will be various bytecode instructions The operand stack writes or extracts data, that is, the stacking and popping operations.
2.13 Dynamic connection: A reference to the method to which the stack frame belongs to the constant pool. This reference is used to support dynamic connection during method invocation. The constant pool of the class file has a large number of symbol references, and the bytecode instructions take the symbol references of the constant pool as parameters. Symbol references are converted to direct references when they are used in a stage, which is called static analysis.
2.14 Return address: There are two main ways to exit, one is where the bytecode instruction is normally pushed, and the other is where the abnormal situation is abnormal. No matter what kind of exit, you need to know the location of the pc counter of the previous method call.

3. ++i and i++ understand local variable table and operand stack

public static void main(String[] args) {
    
    
	a();
	b();
}

public static void a() {
    
    
	int i = 5;
	int j = i++;
	System.out.println(j);
}

public static void b() {
    
    
	int i = 6;
	int j = ++i;
	System.out.println(j);
}

-- 输出结果如下:
Connected to the target VM, address: '127.0.0.1:62076', transport: 'socket'
5
6
Disconnected from the target VM, address: '127.0.0.1:62076', transport: 'socket'

3.1 byteCode

 // access flags 0x9
 public static a()V
	L0
	 LINENUMBER 11 L0
	 // int类型5 压入栈
	 ICONST_5
	 // index为0 保存到局部变量表
	 ISTORE 0
	L1
	 LINENUMBER 12 L1
	 // index为0 从局部变量表压到栈
	 ILOAD 0
	 // 通过常量增加局部变量
	 IINC 0 1
	 // index为1 保存到局部变量表
	 ISTORE 1
	L2
	 LINENUMBER 13 L2
	 GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
	 ILOAD 1
	 INVOKEVIRTUAL java/io/PrintStream.println (I)V
	L3
	 LINENUMBER 14 L3
	 RETURN
	L4
	 LOCALVARIABLE i I L1 L4 0
	 LOCALVARIABLE j I L2 L4 1
	 MAXSTACK = 2
	 MAXLOCALS = 2
 

 // access flags 0x9
 public static b()V
  L0
   LINENUMBER 17 L0
   // 将int型5 压入栈
   ICONST_5
   // index为0 保存至本地变量
   ISTORE 0
  L1
   LINENUMBER 18 L1
   // 通过常量增加局部变量
   IINC 0 1
   // 本地变量int型 index为0 读取到栈顶
   ILOAD 0
   // 将index为1 保存至本地变量
   ISTORE 1
  L2
   LINENUMBER 19 L2
   GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
   ILOAD 1
   INVOKEVIRTUAL java/io/PrintStream.println (I)V
  L3
   LINENUMBER 20 L3
   RETURN
  L4
   LOCALVARIABLE i I L1 L4 0
   LOCALVARIABLE j I L2 L4 1
   MAXSTACK = 2
   MAXLOCALS = 2

You can see the bytecode file of the a method. The L0 operation puts 5 into the stack and then stores to the local variable table; the
L1 operation is to first ILOAD 0 (that is, load 5 to the value of stack j), and then IINC 0 1 (for Add one operation), and finally ISTORE 1 (i is assigned a value of 6) that is to say, j first gets the value of i as 5 and then performs the ++ operation to assign it to i. In fact, i is still 6 here

The bytecode file of the b method, the L1 operation, is IINC 0 1 (first add one to i is 6), then ILOAD 0 (the value of i is 6 is loaded onto the stack), and finally ISTORE 1 (assignment j is 6) In other words, advanced ++ operation and then assign j

4. Klass model

4.1 Klass model
Insert picture description here
4.2 Ordinary Java class corresponds to instanceKlass class in JVM, it also has the following three word classes
4.21 InstanceMirrorKlass: used to represent java.lang.Class, Class object obtained in Java code, in fact It is an instance of this C++ class, stored in the heap area, the scientific name mirror class
4.22 InstanceRefKlass: used to represent the subclass of the java/lang/ref/Reference class
4.23 InstanceClassLoaderKlass: used to traverse the classes loaded by a certain loader

4.3 Arrays in Java are not static data types, but dynamic data types, which are generated during runtime. The meta-information of Java arrays is represented by subclasses of ArrayKlass:
4.31 TypeArrayKlass: arrays used to represent basic types
4.32 ObjArrayKlass: used An array of reference types

  1. Constant Pool
    5.1 The bottom layer of the constant pool is StringTable and the bottom layer of StringTable is HashTable HashTable. We can see the source code unit, which is the entry, from Java. Next, let’s go to the code to see what happened to the memory and select this Memory.
    Insert picture description here
public static void main(String[] args) {
    
    
    a();
    b();

}

public static void a() {
    
    
    String str = "11";
    String str1 = "11";
}

public static void b() {
    
    
    String str = new String("11");
    String str1 = new String("22");
}

1. String str = "11"; We find that char[] +1, j String +1
will first go to the constant pool to find the constant 11 if it is not, then it will create a String object and load the char array inside the String and then push Going to the constant pool constant pool will create an entry containing 11 data
Insert picture description here
2. The second String str1 = "11";
this line of code found that first went to the constant pool to find 11, and then str1 pointed to the String object pointed to by str

Insert picture description here
3. String str = new String("11");
We will find that there is only String +1. In other words, the data of type 11 already exists, so only new one is needed

Insert picture description here
. 4. String str1 = new String("22" );
first go to the constant pool to find 11, if not found, execute "22" first, which means the same as the first example, which is a String object and a char array, and then execute the new String() constructor to construct a String object

Insert picture description here
Summary:
We found that String str = "11";
if several String objects are generated, then it is one String object.
If several objects are generated in total, then there are two oops (InstanceKlass TypeArrayKlass)

Guess you like

Origin blog.csdn.net/weixin_45657738/article/details/109474297