Java Concurrency - Java Memory Area & JMM

2024. 11. 9. 13:44JAVA & SPRING/자바

반응형

Java Memory Area


The area where data is shared with all threads: Method Area, Heap.

The thread-private data area: Program Counter Register, VM Stack, Native Method Stack.

 

When running a program, the JVM automatically divides the memory it manages into the above areas, each of which has its own purpose and the timing of creation and destruction.

 

The area where data is shared with all threads

 

Method Area

It is mainly used to store class information, constants, static variables, code complied by the just-in-time compiler, and other data that have been loaded by the virtual machine. 

 

Runtime Constant Pool in the Method area

It is used to store various literals and symbolic references generated by the compiler after class loading for subsequent use.

 

* literals: Similar to the concept of constants at the Java language level, including text strings, constant values declared as final, etc.

* Symbolic references: Concepts at the compilation language level (class names, variable names, method names, etc).

 

To distinguish the concepts of several of "constant pools"

1. Constant pool: The constant pool is determined during data compilation and is part of the Class file. It stores constants in classes, methods, interfaces, etc., including string constants. 

2. String Pool/String Constant Pool: It is a part of the constant pool and stores string-type data generated in the compiled class.

3. Runtime Constant Pool: Part of the method area, shared by all threads. After the virtual machine loads the Class, it puts the data in the constant pool into the runtime constant pool.

 

JVM Heap

It is created when the virtual machine starts and is the largest piece of memory managed by the JVM. It is used to store object instances, and almost all object instances are allocated memory here. Because the Java heap is the main area managed by the garbage collector, it is often called the GC heap. 

 

 

The thread-private data area

 

Program Counter Register

It is a small memory space, mainly representing the bytecode line number indicator executed by the current thread. When the bytecode interpreter works, it selects the instruction to be executed by changing the value of this counter. 

 

Java Virtual Machine Stacks

It is created simultaneously with the thread, and the total number is associated with the thread, representing the memory model for the execution of Java methods. When each method is executed, a stack frame is created to store local variable tables, operand stacks, dynamic links, method exits, and other information.

- Local Variable Table: It is allocated during the compilation period and is used to store method parameters and local variables defined within the method. It may be basic types, object references, or a handle pointing to an object or other location related to, and returnAddress types, with Slot as the minimum unit of capacity.

- Operand Stack: It is also often called the operation stack, and each element in the stack can be any Java data type. During the execution of the method, various bytecodes will be directed to write and extract values in the operand stack, that is, push and pop operations.

- Dynamic Linking: Each stack frame contains a reference to the method in the runtime constant pool to which the stack frame belongs. Holding this reference is to support dynamic linking during the method call process.

- Method Exit: Normal exit, the execution engine encounters the bytecode of the method return and passes the return value to the caller. Abnormal exit, when encountering an Exception and the method does not catch the exception, there will be no return value. 

 

Native Method Stacks

It is mainly related to the native methods used by the virtual machine and used to distinguish the division of the Java memory model from the division of the Java memory area. After all, these two divisions belongs to different levels of concepts.

 

 

Java Memory Model


It is an abstract concept that does not actually exist. It describes a set of rules or specifications. Through this set of specifications, the access methods of various variables in the program are defined. In addition, the CPU and compiler need to cooperate with this specification to make it easier for developers to develop multithreaded programs.

 

Since the entity running the program in the JVM is a thread, each thread has its own working memory for storing thread-private data. The Java Memory Model stipulates that all variables are in the main memory, which is a shared memory area that all threads can access. Threads cannot directly operate on the variables in the main memory but must first copy the variables from the main memory to their own working memory, operate on the variables in the working memory to their own working memory, operate on the variables in the working memory, and then write them back to the main memory after completion. Since the working memory is a private area for each thread, different threads cannot access each other's working memory, and communication between threads must go through the main memory. 

 

It should be noted that the division of the JMM and the Java memory area is at a different conceptual level. In other words, the JMM describes a set of rules that control the access methods of various variables in the shared data area and the private data area in the program. The JMM revolves around atomicity, orderliness, and visibility. 

 

The only similarity between the JMM and the Java memory area is that there are both shared data areas and private data areas. In the JMM, the main memory belongs to the shared data area, and to some extent, it should include the heap and the method area, while the working memory data thread private data area, to some extent, should include the program counter, the virtual machine stack, and the local method stack. 

 

Main Memory

It mainly stores Java instance objects. All instance objects created by threads are stored in the main memory, regardless of whether the instance object is a member variable or a local variable in a method, and of course, shared class information, constants, and static variables are also included. Since it is a shared data area, multiple threads accessing the same variable may encounter thread safety issues.

 

Working Memory

It stores all the local variable information of the current method (the working memory stores a copy of the variables in the main memory). Each thread can only access its own working memory; that is, the local variables in the thread are invisible to other threads. Even if two threads execute the same code, they will each create local variables belonging to the current thread in their own working memory, including the bytecode line number indicator and information about related Native methods. So the data stored in the working memory does not have thread safety issues.

 


According to the virtual machine specification, for a member method in an instance object, if the method contains local variables and isiof a basic data type, it will be directly stored in the local variable table of the stack frame structure in the working memory. 

 

If the local variable is of a reference type, then the specific reference address of the object in memory will be stored in the local variable table of the stack frame structure in the working memory, while the specific instance object will be stored in the main memory.

 

However, for the member variables of an instance object, whether it is a basic data type, a wrapper type such as Integer, Double, or a reference type, they will all be stored in the heap area. As for static variables and class-related information itself, they will be stored in the main memory. 

 

 

 

 

반응형