What is the JVM runtime memory structure?

Runtime memory is divided into: heap, Java virtual machine stack, local method stack, program counter, and method area.

Program counter

It can be used for thread recovery. Changing it can be used to execute the next bytecode instruction, jump, etc. It is obviously thread private, occupies very little memory space, and is the only area of the JVM that does not specify any OOM (OutOfMemoryError).

Java virtual machine stack

Used to hold local data that Java threads hold at execution time, such as local variable tables, operand stacks, dynamic links (the current method points to the application of the runtime constant pool), and return addresses (return to the place where it was called). Is thread private and will be assigned a default of 1M (specified by -xss) when a thread is created. A stack frame is created for each method entered and destroyed for each method exited.

A StackOverflowError occurs if you keep entering the stack frame without exiting the stack frame. OOM if there is no memory available when allocating vm stack.

Local method stack

Java Native Interface (JNI) is used when calling Java Native Interface (JNI). The VM can implement it freely. Similar to the Java VM stack, StackOverflowError and OOM occur.

The heap

The main area used to hold Java objects, shared by threads, and collected by GC. You can specify the minimum and maximum space using -xms and -xmx. OOM will occur if space is insufficient.

Do objects have to be in the heap?

Not necessarily, the existence of a just-in-time compiler (which caches compilation results (machine code) without changing the interpretation side) makes escape analysis simple.

Escape analysis is to determine whether the scope of an object is the current method, if not, it indicates that escape may exist. If there is no escape, it is allocated to the stack and destroyed when it exits the stack. Can improve the efficiency of the JVM.

We can try it. Escape analysis is turned on by default.

/** * escape analysis - stack assignment * -xx: -doescapeAnalysis -XX:PrintGc */ public class EscapeAnalysisTest {public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); for (int i = 0; i < 50000000; I++) {50 million times --50 million object allocate(); } System.out.println((System.currentTimeMillis() - start) + " ms"); Thread.sleep(3000); } static void allocate() {// This myObject reference does not go out, and there is no other way to use myObject myObject = new myObject (2020, 2020.6); } static class MyObject { int a; double b; MyObject(int a, double b) { this.a = a; this.b = b; }}}Copy the code

Direct Java -xx :PrintGC executes the class result:

19 ms
Copy the code

Direct Java -xx: -doescapeanaysis -xx :PrintGC

[Allocation Failure (GC) 33280K->496K(125952K), 0.0047785 secs] 0.0008720 secS [GC (Allocation Failure) 66936K->408K(159232K) 0.0006539 secS [GC (Allocation Failure) 66968K->424K(225792K) [GC (Allocation Failure) 133544K->392K(225792K), 0.0006146 secS [GC (Allocation Failure) 133512K->456K, [GC (Allocation Failure) 266696K->312K(354304K), 0.0009039 secS [GC (Allocation Failure) 266552K->312K(621056K), 0.0003459 secs] 263 msCopy the code

The efficiency was improved significantly, and no GC was found.

Methods area

Used to store class metadata, constants, static variables, just-in-time compiled machine code and other data, shared by threads. OOM will occur if space is insufficient. This can be set by -xx :MaxDirectMemorySize.

Constant pool

Static constant pool

Class files that store literal variables and references (symbolic references, see bytecode below) stored during compiler generation, saving bytecode space. Use javap -v to find any class file.

Constant pool: #1 = Methodref #16.#42 // java/lang/Object."<init>":()V #2 = Class #43 // com/study/juc/SyncUnFairLockTest$DiningRoom #3  = Methodref #2.#44 // com/study/juc/SyncUnFairLockTest$DiningRoom."<init>":(Lcom/study/juc/SyncUnFairLockTest$1;) V #4 = Class #45 // java/lang/Thread #5 = InvokeDynamic #0:#50 // #0:run:(Lcom/study/juc/SyncUnFairLockTest$DiningRoom;) Ljava/lang/Runnable; #6 = Class #51 // java/lang/StringBuilder #7 = Methodref #6.#42 // java/lang/StringBuilder."<init>":()V #8 = String #52 // Student id :00Copy the code

Run-time constant pool

It is created at runtime. The difference with static constant pools is that they are created at a different time. References are made using direct references (real memory addresses). The goal is to save space and avoid duplication.

String constant pool

JVM instances are shared globally, while run-time constant pools and static constant pools are scoped by classes.

Direct memory

To avoid copying back and forth between the Java heap and Native heap, direct use of off-heap memory can improve efficiency. NIO’s DirectByteBuffer, for example, refers to out-of-heap memory. OOM will occur if space is insufficient.

This can be set using XX:MaxDirectMemorySize.