What is JVM memory partitioning

The problem is very simple. When the JVM runs our code, it has to use multiple memory Spaces. Different memory Spaces are used to hold different data, and then the code flow is used to make our system run.

To take the simplest example, now that we know that the JVM loads classes into memory for subsequent execution, let me ask you, once those classes are loaded into memory, where do they go? Have you thought about that?

So the JVM must have an area of memory where we can store the classes we write.

All member variables, class variables, methods, local variables, and so on that we define are stored in a block of MEMORY in the JVM.

Methods area

In versions prior to JDK1.8, this represents an area of the JVM. After version 1.8, the name of this area was changed to “Matespace”, which can be interpreted as “metadata space”, of course, this area is mainly used to store information about the various classes we write.

Let me give you an example. There are two classes: User1 has no member variables and User2 has a realName class variable.


public class User1 {
	private String userName = "wangwu";
}
public class User2 {
	private static String realName = "zhangsan";
	private String userName = "lisi";
}

Copy the code

When the two classes are loaded into the JVM, they are stored in the method section (all class variables of the classes are assigned values). The following figure

Program counter (execute code instructions)

We know that the class objects that are loaded into the JVM are the.class files that we wrote after the.java files were compiled.

After compilation, our code is compiled into bytecode that the computer can read. And this.calss file is the bytecode that our code compiled.

Once loaded into memory, the bytecode execution engine starts working. To execute our compiled code instructions, the question arises, do we need a memory space to keep track of which lines of code our bytecode execution engine is currently executing? This particular area of memory is the “program counter”, which is used to record the location of the currently executed bytecode instructions.

Note: When the CPU is switched from thread 1 to thread 2, and then back to thread 1, you need to know where thread 1 is. This is what the program counter is for. Therefore, when the thread again context switches to the previous code, a special record of which bytecode was executed by the current thread is required. Therefore, each thread has its own program counter.

Stack space, also known as the Java virtual machine stack (native method stack).

When a thread executes a method that has a local variable, it needs an area to hold the local variable’s data. This area is called the Java Virtual machine stack.

Each thread has its own Java virtual machine stack, such as a main thread that holds local variables defined in the main method when executing it

public class TestController {

	public static void main(String[] args) {
	    int i = 1;
    	    User1 user1=new User1();
    	    user1.setUserName("sss"); }}Copy the code

For example, in the main() method above, there is a local variable of “user1” that refers to an instance of user1, and a local variable of “I”. The diagram below:

Since it is a stack, it follows the last in, first out principle. When the method completes, the frame is removed from the stack and the local variable information is removed from memory. So local variables are thread-safe. Because only the current thread can get this value.

Q: Why a lifO data structure?

A: Suppose method B is called in method A. At this time, the frame of method A is pushed first, and that of method B is pushed later. When the execution of method B is completed, the frame of method B will be removed from the stack first, and then the frame of method A will be removed from the stack again. So using a lifO stack structure is perfect.

Heap space

Again, when the main thread executes the main() method, it first instantiates the User1 object in the heap and then creates User1 in the local variable, which holds the memory address of the instantiated User1 object. The getName() method of the Student object is then executed.

The diagram below:

Out of memory

In fact, in many of the JDK’s underlying code apis, such as NIO.

If you look at the source code, you will find that many places of code is not written in Java, but go to the native method to call some methods in the local operating system, may call methods written in C language.

Such as:

public native int hashCode();

public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2);
Copy the code

When calling this native method, there is a thread corresponding to the local method stack, which is actually similar to the Java virtual machine stack. It is also used to store information such as local variable scale of various native methods.

There is also an area, not JVM, that can be allocated out of the JVA heap through the allocateDirect API in NIO, which can then be referenced and operated on through the DirectByteBuffer in the Java VIRTUAL machine stack.

Focus on: method areas, program counters, Java virtual machine stack, and Java heap memory