Is heap the only option for allocating objects?

I. escape analysis

In the in-depth understanding of Java virtual machine, there is a paragraph about Java heap memory:

With the development of JIT compiler and the maturity of escape analysis technology, stack allocation and scalar replacement optimization technology will lead to some subtle changes, and all objects are allocated to the heap, which will gradually become less "absolute".

In the Java virtual machine, it is a common knowledge that objects allocate memory in the Java heap. However, there is a special case, that is, if an object is found to have no escape method after Escape Analysis, it may be optimized to be allocated on the stack. This eliminates the need to allocate memory on the heap and garbage collection. This is also the most common off heap storage technology.

In addition, TaoBaovm is deeply customized based on openJDk, in which the innovative GCIH (GC invisible heap) technology realizes off heap, moves Java objects with long life cycle from the heap to outside the heap, and GC cannot manage Java objects inside GCIH, so as to reduce the recovery frequency of GC and improve the recovery efficiency of GC.

How to allocate objects on the heap to the stack requires escape analysis.

This is a cross function global data flow analysis algorithm that can effectively reduce the synchronization load and memory heap allocation pressure in Java programs.

Through escape analysis, the Java Hotspot compiler can analyze the use range of the reference of a new object and decide whether to allocate the object to the heap.

The basic behavior of escape analysis is to analyze the dynamic scope of the object.

  • When an object is defined in a method and the object is only used inside the method, it is considered that there is no escape.

  • When an object is defined in a method and referenced by an external method, it is considered to have escaped. For example, pass it elsewhere as a call parameter.

II. Actual combat - there was no escape

1. Code

public void my_method() {
    V v = new V();
    // use v
    // ....
    v = null;
}

2. Description

new V() of the above code; If there is no escape, it can be allocated to the stack. With the end of method execution, the stack space will be removed.

III. actual combat - escape occurred

1 code

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

2. Description

new StringBuffer() has escaped. After return, the object has escaped outside the method. This object cannot be allocated on the stack.

If you want the new StringBuffer() object not to escape, you can rewrite it to the following code.

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

At this time, the new StringBuffer() object will not escape from the method, and it can be allocated on the stack.

IV. actual combat - complete escape analysis

/**
* escape analysis
* <p>
* How to quickly judge whether escape occurs depends on whether the object entity of new can be called outside the method.
*/
public class EscapeAnalysis {
    public EscapeAnalysis obj;

    /*
    Method returns the EscapeAnalysis object, and an escape occurs
     */
    public EscapeAnalysis getInstance() {
        return obj == null ? new EscapeAnalysis() : obj;
    }

    /*
    An escape occurred while assigning a value to a member property
    If the current obj reference is declared as static, escape will still occur.
     */
    public void setObj() {
        this.obj = new EscapeAnalysis();
    }

    /*
    The scope of the object is only valid in the current method, and no escape has occurred
     */
    public void useEscapeAnalysis() {
        EscapeAnalysis e = new EscapeAnalysis();
    }

    /*
    Reference to the value of member variable, escape occurred
     */
    public void useEscapeAnalysis1() {
        EscapeAnalysis e = getInstance();
        // getInstance().xxx() will also escape
    }
}

Five parameter setting

After the JDK 6u23 (JDK 7) version, escape analysis has been enabled by default in HotSpot.

If an earlier version is used, developers can set it through the following parameters.

  • The option "- XX:+DoEscapeAnalysis" explicitly turns on escape analysis.

  • View the filter results of escape analysis through the option "- XX: + printescape analysis".

Vi. conclusion

If local variables can be used in development, do not use definitions outside the method.

Keywords: jvm

Added by imderek on Wed, 19 Jan 2022 22:34:03 +0200