Introduction:
A previous article combed the principle of the invariance of string, but also referred to a section of the source code annotated "avoid GetField opcode", at that time by looking at the data found that this is to prevent the GetField (get the instance domain of the specified class, and put its value into the top of the stack) This operation code execution, This article wants to analyze from the point of view of bytecode.
Let's look at some code.
/** * Created by Chenqimiao on 16/11/29. */public class Main { public char[] chars = new CHAR[10]; public void Test () { System.out.println (chars[0]); System.out.println (Chars[1]); System.out.println (chars[2]); } public static void Main (String args[]) { main m = new main (); M.test (); }}
Execute javap-c Main , analyze the bytecode, and look at the opcode generated after the analysis:
Check out the virtual machine bytecode instruction table in the "Deep understanding JVM Virtual Machine" book and try to analyze the code below the test method.
4. Gets the specified instance field and pushes its value to the top of the stack
7. Push int type 0 to the top of the stack
8. Push the value of the specified index of the char array to the top of the stack
9. Invoking an instance method
To summarize, it is every time that the instance domain is pushed to the top of the stack, then the index of the operation is pushed to the top of the stack, then the value of the specified index of the corresponding array is pushed to the top of the stack, then the output method is called. Can see the output three times, the GetField operation code is called three times, imagine we are traversing this char array, that like the above notation, to call GetField opcode frequently.
Let's learn the wording of string source code, which may improve the problem.
/** * Created by Chenqimiao on 16/11/29. */public class Main { public char[] chars = new CHAR[10]; public void Test () { char[] chars = this.chars; System.out.println (Chars[0]); System.out.println (Chars[1]); System.out.println (chars[2]); } public static void Main (String args[]) { main m = new main (); M.test (); }}
Execute javap-c Main, analyze the bytecode, and look at the opcode generated after the analysis:
Well, I've assigned a reference to the array of the instance variable to a local reference.
Let's just analyze the code in the test method
0. Push the first reference type local variable to the top of the stack (that is, place the local variable reference chars on top of the stack)
1. Get a reference to the instance field pushes to the top of the stack (the member of the instance variable chars to the top of the stack)
4. Deposit Top-top reference type value into the specified local variable (that is, the reference to the member variable chars to the local variable reference chars, here is the reference value copy, not a reference to the memory of the value of the copy)
5. Gets the specified instance field and pushes its value to the top of the stack
8. Push the second reference type local variable to the top of the stack
9. Push int type 0 to the top of the stack
10. Press the value of the index specified by the char array into the top of the stack
11. Invoking an instance method (output)
In the 14-20 process, no more "GetField" operation, but the second local reference (the assigned value of the local reference chars) is pushed to the top of the stack with the aload_1 opcode, you can perform the next series of operations.
Here the word "avoid getfield opcode" means it is clear that when iterating through the instance's char array, the reference to the instance array is assigned to a local reference, without the need to call the operation code "GetField" Frequently, Only the first time to assign a value to a local reference, call the GetField, the next iteration of the value, only need to press the local reference to the top of the stack.
"Avoid GetField opcode" in string source