Escape analysis concept
With the development of jtl compiler and the maturity of escape analysis technology, stack allocation and scalar substitution optimization technology will lead to the conclusion that objects are allocated to the heap. If an object does not escape from the method after escape analysis, it may be optimized to station allocation, Whether an object escapes is determined by judging whether the object is possible to be used outside the method.
Escape analysis is a cross functional global data flow analysis algorithm that can effectively reduce the synchronization load and memory heap allocation pressure in java programs.
Escape analysis switch
It is turned on by default, but can be turned on and off through the parameter - XX:+DoEscapeAnalysis
Escape scenario analysis
package com.lydon.test; public class EscapeAnalysis { private EscapeAnalysis escapeAnalysis; /** * Method returns the object directly, and escapeAnalysis is the object that has escaped * @return */ public EscapeAnalysis getInstance(){ if(escapeAnalysis==null){ escapeAnalysis=new EscapeAnalysis(); } return escapeAnalysis; } /** * If the object is directly exposed outside the method, it may be used by other methods, and escape occurs * @param */ public void setObj(){ this.escapeAnalysis=new EscapeAnalysis(); } /** * Object is used internally, so there is no escape */ public void useEscapAnalysis(){ EscapeAnalysis escapeAnalysis=new EscapeAnalysis(); } /** * getInstance The object is returned, and this method also escapes */ public void useEscapAnalysis2(){ EscapeAnalysis escapeAnalysis=getInstance(); } /** * Escape object after escape analysis * @return */ public static StringBuilder createStringBuilder(){ StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("1"); stringBuilder.append("2"); return stringBuilder; } /** * For the object that has not escaped after escape analysis, put the stringbuilder inside the method * @return */ public static String createStringBuilderNoEscapeAnalysis(){ StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("1"); stringBuilder.append("2"); return stringBuilder.toString(); } }
The conclusion is that the variables that can be defined in the method are defined in the method, not as member variables.
Escape analysis - code optimization
Based on the escape analysis, the jvm can automatically take some optimization measures, such as on stack allocation, synchronous omission and scalar replacement. It should be noted that these optimization measures are optimized during the compilation of the executor, not during the generation of bytecode.
1. On stack allocation
After escape analysis, it is found that there is no escape phenomenon, so the object can be a candidate for stack allocation and can be optimized into stack allocation instead of heap allocation. After calling the stack, the stack will pop up and local variables will be recycled, so there is no need for garbage collection. For scenes that cannot be allocated on the stack, assign values to member variables, return object instances, and pass instance references (that is, scenes in the above code segment that belong to escape phenomenon after escape analysis).
Write a code to try the difference between turning on and off escape analysis:
package com.lydon.test; public class StackAllocation { public static void main(String[] args) { long start=System.currentTimeMillis(); for (int i=0;i<1000000000;i++){ alloc(); } long end=System.currentTimeMillis(); System.out.println("Time consuming:"+(end-start)); try { Thread.sleep(10000000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void alloc(){ User user=new User(); } } /** * */ class User{ private int age; private String name; }
Closing - Xms1g -Xmx1g -XX:-DoEscapeAnalysis time consuming: 5310
It was found that many objects were allocated in the heap
Open - Xms1g -Xmx1g -XX:+DoEscapeAnalysis time: 15
No allocation was found in the heap
2. Synchronous ellipsis
If it is found that an object can only be accessed by one thread, the operation on this object can be unlocked, which is also called lock elimination
public void lock(){ Object o1=new Object(); //Because each thread will generate an o1 lock, it is unnecessary to add a lock here. o1 is not a public lock, so the jvm removes the lock after escape analysis synchronized (o1){ System.out.println("111"); } } public void lock2(){ Object o1=new Object(); System.out.println("111"); }
3. Detach object or scalar substitution
Some objects can be accessed without continuous memory structure, so they can be disassembled into local variables and stored in pc registers.
Scalar: refers to data that can no longer be disassembled
Aggregate quantity: data that can be decomposed. java objects are aggregate quantities
In the JIT stage, after escape analysis, the objects that will not escape are disassembled into scalars (local variables) for replacement, so as to achieve the purpose of allocation on the stack. The following is an example of replacement:
/** * Scalar parsing instance before replacement */ public static void alloc2(){ Point point = new Point(1,2); System.out.println(point.x+point.y); } /** * Scalar analysis instance replaced after escape analysis */ public static void allocAfter(){ int x=1; int y=1; System.out.println(x+y); }
Scalar substitution is turned on by default, and can also be turned on or off through the parameter - XX:+EliminateAllocations
Not open: - Xms1g -Xmx1g -XX:+DoEscapeAnalysis -XX:-EliminateAllocations
Time: 6094
On: - Xms1g -Xmx1g -XX:+DoEscapeAnalysis -XX:+EliminateAllocations
Time: 22
It can be seen here that once scalar substitution is turned off, it is useless to turn on escape analysis.
Summary of escape analysis
Only in server mode can escape analysis be enabled, - server
Although on stack allocation, lock elimination and scalar replacement can be done based on escape analysis, the current escape analysis is not very mature, because the amount of escape analysis itself takes time. It is difficult to say that the time spent on escape analysis will be shorter than that for optimization after analysis. oracle jvm does not realize on stack allocation, The current escape analysis is based on the implementation of scalar substitution, but once scalar substitution is carried out, it actually becomes a local variable, so the conclusion that object instances are allocated on the heap is still correct.