Road jvm exploration - method based on the execution stack mechanism

Due

This week regular meeting, during code review, a colleague of which define the position of a variable method of questioning

    // 为了方便,对代码进行了简化
		public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            int a = 1;
            int b = 2;
            System.out.println(a + b);
        }
    }
复制代码

He thought for a loop a, b method mentioned external definition will be better, but also specific reason was not clear, some colleagues also link the operational performance of the garbage collector.

But standing in my point of view, the difference between the two, in addition to the scope of the program-level variables changed in the method of operation is no significant difference in the level, just to recap here also related to the operation of the mechanism jvm method.

VM stack

jvm runtime memory there is an area called the plan a virtual machine stack, the thread is divided into private space, running thread in the region should approach the stack frame of the stack, the stack, a method corresponds to a stack frame.

It can be seen from the above figure, the stack frame unit into four sections: the local variable table, the operand stack, dynamic linking, return address.

Local variable table

The method of storing local variables required to run: the local variable parameter method, internally defined.

The minimum storage unit Slot (variable slot) , the spatial size of 4 bytes, so as boolean, byte, char, short, int, float, reference need only occupy a variable slot, and long, double the need to occupy two variables groove.

Therefore, the local variable table size can be determined at compile time, and not so much running or not.

Here is a simple example

    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = a + b;
    }
复制代码

Corresponding to the local variable table: Slot here focus on what value, which is defined according to the index value assigned to the variable sequence (e.g., a method args parameter that is defined in the first local variable, so the slot args = 0)

  LocalVariableTable:
    Start  Length  Slot  Name   Signature
        0       9     0  args   [Ljava/lang/String;
        2       7     1     a   I
        4       5     2     b   I
        8       1     3     c   I
复制代码

There are two interesting points about the local variable table can explore, this article does not involve the first piece of content.

  • Storage space between the stack frame multiplexing (operand stack and local variable table, a method for transmitting call parameters)
  • Local variable table (garbage collection might affect the object) of multiplexed Slot

Operand stack

Storing operation for instruction execution of the required operand, the continuation of a simple example

    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = a + b;
    }
复制代码

Corresponding method bytecode instruction set:

0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: return
复制代码

Briefly explain a few instructions

  • iconst constant corresponding to the operand stack into the operand stack, Example 1 is placed iconst_1
  • istore the value of the operand stack local variable table element is written to the specified slot, e.g. istore_1 operand stack is the value of the local variable table element is written to variable slot = 1
  • iload slot specified local variable values ​​into the operand stack, local variable is iload_1 Example Table 1 slot = variable value into the operand stack
  • Iadd two elements of the operand stack pop, the + operation performed, then the result will be pressed back operand stack

Examples of the above-described execution code as follows:

  • Constant stack 1, the top element assigned to the local variable table to the variable a = "iconst_1, istore_1
  • Constant stack 2, the top element is assigned to the local variable table variable b = "iconst_2, istore_2
  • The local variable table variables a, b values ​​of stack = "iload_1, iload_2
  • The first two elements of the pop stack, for operation + the result stack = "iadd
  • The top element, i.e. the calculation result is assigned to the local variable table variable c = "istore_3

As can be seen, the operand stack will instantly refresh operation result to the local variable table corresponding to the variable.

For dynamic link here, as well as the return address is not being discussed, not the focus of this article.

Analysis bytecode

Talking about this, I am sure the interpretation method of enforcement mechanisms jvm have a certain understanding, we are back to the beginning of the following examples, explore the issue of local variables defined position.

Use javap command look bytecode program corresponding to the content files, primarily concerned with the local variable table that is used to store local variables defined in the method, defined sequence, we can see a, b are allocated in slot 3 (slot), the operand stack operation need this slot index (istore_2, the latter refers to the number of instructions iload_2 slot index)

 LocalVariableTable:
        Start  Length  Slot  Name   Signature
           10      11     2     a   I
           12       9     3     b   I
            2      25     1     i   I
            0      28     0  args   [Ljava/lang/String;

复制代码

If we take the local variables defined outside of the for loop

    // 为了方便,对代码进行了简化
		public static void main(String[] args) {
        int a;
        int b;
        for (int i = 0; i < 100; i++) {
						a = 1;
          	b = 2;
            System.out.println(a + b);
        }
    }
复制代码

Byte code corresponding to the local variable table, we can see a, b in addition to the index variable is changed groove slot (defined as a change in the order), others are the same, the method at the implementation level, they can be considered identical.

      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           10      17     1     a   I
           12      15     2     b   I
            2      25     3     i   I
            0      28     0  args   [Ljava/lang/String;

复制代码

Now we look at the bytecode instruction corresponding method, you can see the contents of almost the same, except istore, iload instructions differences, because a, b the change in the index variable slot, at the implementation level method, you can also think they are consistent.

 // 局部变量定义在方法外部
 Code:
      stack=3, locals=4, args_size=1
         0: iconst_0
         1: istore_3
         2: iload_3
         3: bipush        100
         5: if_icmpge     27
         8: iconst_1
         9: istore_1
        10: iconst_2
        11: istore_2
        12: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        15: iload_1
        16: iload_2
        17: iadd
        18: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        21: iinc          3, 1
        24: goto          2
        27: return
        
 // 局部变量定义在方法内部
    Code:
      stack=3, locals=4, args_size=1
         0: iconst_0
         1: istore_1
         2: iload_1
         3: bipush        100
         5: if_icmpge     27
         8: iconst_1
         9: istore_2
        10: iconst_2
        11: istore_3
        12: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        15: iload_2
        16: iload_3
        17: iadd
        18: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        21: iinc          1, 1
        24: goto          2
        27: return


复制代码

in conclusion

From the experimental phenomenon, local variables defined in the outer loop circulating inside vs local variables defined in the

  • Local variable table bytecode both methods are consistent
  • Both bytecode execution instruction corresponding method are consistent

From these two basic latitudes can confirm no doubt, both in the running level is not significantly different.

Guess you like

Origin juejin.im/post/5e7b4a585188255e354fed26