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.