[Performance optimization] Interviewer: Are objects in Java necessarily allocated on the heap?

Write in front

From the beginning of learning Java, we have come into contact with the view: Objects in Java are created on the heap and references to objects are placed on the stack. Is this view really correct? If it is correct, then why would the interviewer ask: "Are objects in Java necessarily allocated on the heap?" What about this question? It seems that this view that we have been instilled from Java is worth doubting.

About interview questions

The interview question in the title is: Are objects in Java necessarily allocated on the heap?

When the interviewer asks, some friends will think in their minds: I knew from the beginning of learning Java: Objects in Java are created on the heap, and references to objects are stored on the stack, so objects in Java It is allocated on the heap! Is not it?

Insert picture description here

If you answer this way, you will be passed directly.

Maybe some friends still don't understand, then we continue to look down.

Interview Question Answer

First of all, we give the answer to this question first. Here I will answer this interview question briefly, and we will conduct related analysis later.

You can answer this: Objects in Java are not necessarily allocated on the heap, because the JVM can analyze the scope of use of a new object through escape analysis and determine whether to allocate this object to the heap.

Here, we are exposed to a new term: escape analysis. I believe that many friends do not understand very well, so let's continue to look down.

Insert picture description here

Escape analysis

The concept of escape analysis

First, let's talk about escape analysis in official form. Escape analysis is: a static analysis to determine the dynamic range of the pointer, which can analyze where the pointer can be accessed in the program.

In the context of JVM just-in-time compilation, escape analysis will determine whether the newly created object escapes. Just-in-time compilation judges whether the object escapes: one is whether the object is stored in the heap (static field or the instance field of the object in the heap), and the other is whether the object is passed into unknown code.

Speaking of these concepts directly, it is indeed a bit dizzy, so let's take two examples.

Insert picture description here

Object escape example

A typical object escape is: the object is copied to a member variable or static variable, and may be used externally, at this time the variable escapes.

We can use the following code to represent this phenomenon.

/**
 * @author binghe
 * @description 对象逃逸示例1
 */
public class ObjectEscape{
    
    
    private User user;
    public void init(){
    
    
        user = new User();
    }
}

In the ObjectEscape class, there is a member variable user. In the init() method, we create an object of the User class and assign it to the member variable user. At this time, the object is copied to the member variable and may be used externally, and the variable at this time escapes.

Another typical scenario is: the object is returned through the return statement. If the object is returned through the return statement, the program at this time is not sure whether the object will be used in the future, the external thread can access this variable, and the object escapes at this time.

We can use the following code to represent this phenomenon.

/**
 * @author binghe
 * @description 对象逃逸示例2
 */
public class ObjectReturn{
    
    
    public User createUser(){
    
    
        User user = new User();
        return user;
    }
}

Given two examples, I believe you have a little understanding of JVM escape analysis, yes, JVM can analyze the scope of use of new objects through escape analysis, so as to determine whether the new objects should be allocated on the heap.
Insert picture description here

We are not over yet, let's continue to look at the advantages of escape analysis, so that friends can better understand escape analysis.

Advantages of escape analysis

The advantages of escape analysis can generally be divided into three: objects may be allocated on the stack, object separation or scalar replacement, and synchronization lock elimination. We can use the following figure to represent.
Insert picture description here

Objects may be allocated on the stack

JVM analyzes the scope of use of new objects through escape analysis, and may allocate objects on the stack. Stack allocation can quickly create and destroy objects on the stack frame, without having to allocate objects to the heap space, which can effectively reduce the pressure of JVM garbage collection.

Separate objects or scalar replacement

When the JVM determines that the object is to be allocated on the stack through escape analysis, just-in-time compilation can break up the object and replace the object with a small local variable. We call this break up process scalar replacement. After replacing the object with a local variable, it can be easily allocated on the stack.

Genlock elimination

If the JVM finds that an object can only be accessed from one thread through escape analysis, it is not necessary to add a synchronization lock when accessing this object. If a synchronized lock is used in the program, the JVM will eliminate the synchronized lock.

Here, it should be noted that this situation is aimed at synchronized locks, and for Lock locks, the JVM cannot eliminate it.

To enable synchronization elimination, you need to add the -XX:+EliminateLocks parameter. Because this parameter depends on escape analysis, the -XX:+DoEscapeAnalysis option must be turned on at the same time.

Therefore, not all objects and arrays are allocated on the heap. Due to the existence of just-in-time compilation, if the JVM finds that some objects have no escape method, they are likely to be optimized for allocation on the stack.

Guess you like

Origin blog.csdn.net/l1028386804/article/details/108721747