This is the 16th day of my participation in Gwen Challenge

“Tramp…” A knock on the door jolted me out of my dream.

“Ah Q, are you at home?”

“Come, come!” He opened the door and found brother Zhao Xin.

Zhao letter: call oneself changshan Zhao Zilong, a three claw long gun play of tiger tiger unripe wind, see a person go up is a gun, the person send nickname “chrysanthemum letter”.



\

TLAB

























  • Although not all object instances can be inTLABIs successfully allocated memory (because it has less space), butJVMClear is toTLABAs the preferred memory allocation;
  • Once the object is inTLABWhen space allocation memory fails,JVMAttempts are made to ensure atomicity of data operations through the use of locking mechanisms, thus directly inEdenAllocate memory in space.

    \

Parameter Settings

  • -XX:UseTLAB: Indicates whether to enable the functionTLABSpace;
  • -XX:TLABWasteTargetPercentSet:TLABSpace occupiedEdenPercentage of space. Default value1%;



Is the heap the only option for allocating objects?









  1. If through escape analysis (Escape Analysis), an object that does not escape the method may be optimized for stack allocation. This eliminates the need to allocate memory on the heap and garbage collection. This is also the most common out-of-heap storage technique.
  2. Based on theOpenJDKDeeply customizedTaoBaoVMIt’s innovativeGCIH(GCinvisible heap)Out-of-heap allocation is implemented. Will have a longer life cycleJavaObject is moved from the heap to outside the heap, andGCCan’t manageGCIHThe inside of theJavaObject to reduce the frequency of GC collection and improveGCThe purpose of recycling efficiency.







For example, a

public void method(a){
    User user = newUser(); . user =null;
}
Copy the code

If the user object is declared inside the method and set to null internally, and is not referenced by any method outside the method, we say that the user object has not escaped.

It can be allocated to the stack and the stack space is removed as the method terminates.

For example, two

public static StringBuffer createStringBuffer(String s1,String s2){
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    return sb;
}
Copy the code

An sb object is said to have escaped, even though it is defined inside a method but can be called by other methods as a return object of that method.

To avoid escape, it can be transformed into:

public static String createStringBuffer(String s1,String s2){
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    return sb.toString();
}
Copy the code





Escape analysis is enabled by default in HotSpot after JDK 6U23.

  • -XX:DoEscapeAnalysis: Explicitly turn on escape analysis
  • -XX:+PrintEscapeAnalysis: View the filter results of escape analysis





On the stack



/** * Allocate test on stack * -XMx1g-xMS1g-xx: -doescapeAnalysis -xx :+PrintGCDetails */
public class StackAllocation {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        for (int i = 0; i < 10000000; i++) {
            alloc();
        }
       
        long end = System.currentTimeMillis();
        System.out.println("The time spent is:" + (end - start) + " ms");
        // To check the number of objects in the heap, the thread sleep
        try {
            Thread.sleep(1000000);
        } catch(InterruptedException e1) { e1.printStackTrace(); }}private static void alloc(a) {
        // No escape occurred
        User user = new User();
    }

    static class User {}}Copy the code

Escape analysis is enabled by default or manually: -xx :+DoEscapeAnalysis

Shut-off escape analysis



Synchronous omit



We all know that thread synchronization is very expensive, and the result of synchronization is reduced concurrency and performance.

When a SYNCHRONIZED block is dynamically compiled by the JVM to improve performance, the JIT compiler can use escape analysis to determine whether the lock object used by the synchronized block is accessible to only one thread.

If so, the JIT compiler unsynchronizes the code when it compiles the synchronized block. This unsynchronization process is called synchronization elision, also known as lock elimination.

For example,

public class SynchronizedTest {
    public void method(a) {
        Object code = new Object();
        synchronized(code) { System.out.println(code); }}/** * The code object is locked, * but the life of the code object is only in the method method and is not controlled by other threads, * so it is optimized for JIT compilation. * /
    
    / / for optimization
    public void method2(a) {
        Object code = newObject(); System.out.println(code); }}Copy the code

There is still a lock in the interpreted execution, but after an in-flight compilation by the server-side compiler, the code will ignore all synchronization measures and execute directly.

Scalar replacement

  • Scalar: a quantity that cannot be further decomposed, asJAVAThe basic data type of is scalar;
  • The quantity that can be further decomposed, atJAVAAn object is an aggregate that can be further decomposed.

Aggregate quantities can be decomposed into other scalars and aggregate quantities.

Scalar replacement, also known as separated objects, that is, in the JIT stage, if an object is not found to be accessed by the outside world after escape analysis, then after JIT optimization, the object will be disintegrated into several member variables contained in it to replace it.

For example,

public class ScalarTest {
    public static void main(String[] args) {
        alloc();   
    }
    public static void alloc(a){
        Point point = new Point(1.2); }}class Point{
    private int x;
    private int y;
    public Point(int x,int y){
        this.x = x;
        this.y = y; }}// Change to
public static void alloc(a){
    int x = 1;
    int y = 2;
}
//Point is an aggregation quantity that does not escape and is replaced by two scalars.
Copy the code

Scalar substitution is on by default, or you can set it manually with the parameter -xx :+EliminateAllocations, which allows objects to be split and allocated to the stack, less GC, and faster execution.

A common scenario in which escape occurs



For example,

public class EscapeAnalysis {

    public EscapeAnalysis obj;
    
     /* To assign a value to a member attribute, escape occurs */
    public void setObj(a){
        this.obj = new EscapeAnalysis();
    }
    // Consider: what if the current obj reference is declared static? Escape still happens.

    /* The EscapeAnalysis method returns the EscapeAnalysis object, which occurs */
    public EscapeAnalysis getInstance(a){
        return obj == null? new EscapeAnalysis() : obj;
    }
   
   
    /* References the value of a member variable, an escape occurs */
    public void useEscapeAnalysis1(a){
        EscapeAnalysis e = getInstance();
        //getInstance().xxx() will also escape
    }
    
     /* The scope of the object is only valid in the current method, no escape */ has occurred
    public void useEscapeAnalysis(a){
        EscapeAnalysis e = newEscapeAnalysis(); }}Copy the code

Escape analysis is immature







Escape analysis was first published in 1999, but it was only implemented in JDK1.6, and the technology is still not fully developed.

The fundamental reason is that there is no guarantee that the performance improvement of escape analysis will be greater than its consumption, because escape analysis itself requires a series of complex and time-consuming analyses.

An extreme example would be to go through escape analysis and find that all objects have escaped, so the process of escape analysis is wasted.

If you’re careful, you’ll notice that the screenshot we take in the sampler is actually the object allocated in the heap.

That’s all for today’s content. If you have different opinions or better ideas, please contact Ah Q: Qingqing-4132. Ah Q can invite you to join the technical group to discuss technology together. Ah Q is looking forward to your arrival!