Dead Concurrency Java Memory Model (Java Memory Model)

Java Memory Model JMM

java memory model definition

In the last article, we talked about CPU cache coherence and memory barrier issues. Then, as a cross-platform language, Java needs to face different underlying hardware systems for its implementation, design a middle-tier model to shield the underlying hardware differences, and give upper-level developers a consistent use interface. The Java memory model is such a middle-level model, which shields the underlying hardware implementation details for programmers and supports most mainstream hardware platforms.

Java Memory Mode: The java memory model is how the java virtual machine memory works with computer memory (RAM). The Java virtual machine is a model of the entire computer, so this model naturally includes a memory model. It can also be said that JMM is the Java virtual machine memory usage specification.

In layman's terms, it describes the access rules of various variables (thread shared variables) in Java, as well as the underlying details of storing and reading variables in and out of memory in the JVM.

The Java memory model dictates how and when different threads can see values ​​written to shared variables by other threads and how to synchronize access to shared variables when necessary .

Note: The Java Memory Model does not really exist, it is just a mapping of the physical memory model.

Introduction to the Java Memory Model


Two concepts of memory allocation in the JVM:

  1. stack (stack)
    features: fast access speed, object life cycle is determined, data size is determined.
    Store data: basic type variables, object references (handles)
    Location: caches, registers, write buffers.

  2. Heap (heap)
    characteristics: slow access speed, dynamic allocation size at runtime, uncertain object life cycle, garbage collection.
    Store Data: Object
    Location: Main Memory, Cache

In theory, all stacks and heaps are stored in physical main memory, but as the CPU operates, copies of its data may be held in caches or registers, and the held data follows a coherency protocol .

storage method

As mentioned above, an object is stored on the heap, and the method and method member variables of the object are stored on the stack. An object's member variables are stored on the heap along with the object itself , regardless of whether the object type is a reference type or a primitive type. Static variables and object class definitions are stored on the heap.

Concurrency reasons

Objects stored on the heap can be accessed by the stack holding a reference to the object. If you can access the object, you can also access the member variables in the object. When two threads access an object at the same time, each thread has a private copy of the object's member variables .

Here is just a rough allocation of the java memory model. For specific details on memory allocation, see
Overview of JVM Memory Management

Java Memory Model and System Memory Model

Let's take a look at a relationship diagram:

There is no concept of stack and heap in the system memory architecture, only registers, caches, and main memory (RAM, Main Memory). In theory all stacks and heaps are stored in main memory, but as the CPU operates a copy of its data may be held in caches or registers. The held data conforms to the CPU-Cache coherency protocol .

For CPU memory model and coherence protocol, please refer to the previous article: CPU Cache Coherence Protocol (MESI) for Dead Concurrency

Java memory model abstract structure diagram

Main memory : holds all variables.

Shared variable : If a variable is used by multiple threads, then this variable will keep a copy in the working memory of each thread. This kind of variable is a shared variable.

Such as member variables, static variables, array elements, etc.

Working memory : Each thread has its own working memory, which is shared exclusively by the thread, and saves a copy of the variable used by the thread (a copy of the main memory shared variable). Working memory is responsible for interacting with threads, but also for interacting with main memory. For higher efficiency, the Java virtual machine and hardware system may allow work to be preferentially allocated in registers and caches.

JMM makes the following two regulations for the operation of shared memory:

  • All operations on shared memory by a thread must be performed in its own working memory, and cannot be directly read or written from main memory.
  • Different threads cannot directly access variables in the working memory of other threads, so the value transfer of shared variables needs to be done through main memory.

The root of java concurrency problem

Suppose that thread A and thread B colleagues access the member variable x of an object. When thread a needs to manipulate variable a, a copy of a is copied to thread A's working memory.

When thread a has not finished executing, thread b also needs to access variable a

But thread a and thread b operate on copies of variables in their own workspaces. The copy in thread a is invisible to the copy in thread b. If thread a completes the task first and writes back to main memory. Then the operation of thread b is the dirty data operation after use. If b also writes back to main memory then thread a's task is lost.

In order to ensure the accuracy of the program, we need to add additional synchronization operations during concurrency.

Java memory model - eight synchronization operations between memory

Operation process

Next, let's focus on the details of reading variables from main memory to working memory, and then synchronizing them back to working memory. This is the interaction protocol between main memory and working memory. The Java memory model defines the following 8 operations to be performed, all of which are atomic (except for variables of type long and double).

Lock (lock) : Act on a variable in main memory, marking it as a thread-exclusive variable.

Locking in the usual sense means that when a thread is in use, other threads must wait for the thread's task to complete before continuing to execute their own tasks.

Unlock (unlock) : Act on the variables in the main memory, release the locked state of the variables, and the variables in the unlocked state can be locked by other threads.

Unlock after execution is complete.

read : A variable acting on main memory, which transfers the value of a variable from main memory to the thread's working memory for subsequent load actions.

Read from main memory into working memory.

load (load) : Put the variable value obtained by the read operation from main memory into a copy of the variable in working memory.

Assign a value to the copy in working memory.

use : Pass the value of a variable in working memory to the execution engine, which is used whenever the virtual machine encounters an instruction that uses the variable.

Called when the value is read during program execution.

assign (assignment) : a variable that acts on working memory, it assigns a value received from the execution engine to a variable in working memory, and executes this operation whenever the virtual machine encounters a bytecode instruction that assigns a value to the variable.

Assigning the new value after the operation is completed to the variable in the working memory is equivalent to modifying the variable in the working memory.

store (storage) : a variable acting on working memory, which transfers the value of a variable in working memory to main memory for subsequent write operations.

Take the value out of the variable and write it into working memory.

write (write) : a variable that acts on the main memory, which puts the value of the variable obtained from the working memory by the store operation into the variable in the main memory.

Write the value in working memory back to main memory.

~TODO still owes two read flow charts here~

operating rules

  • One of read and load, store and write operations is not allowed to appear alone, that is, a variable is not allowed to be read from main memory but not accepted by working memory, or a write-back is initiated from working memory but not accepted by main memory.

  • A thread is not allowed to discard its most recent assign operation, that is, after a variable has changed in working memory, it must synchronize the change back to main memory.

  • A thread is not allowed to synchronize data from the thread's working memory back to main memory for no reason (no assign operation has occurred).

  • A new variable can only be "born" in the main memory, and it is not allowed to use an uninitialized (load or assign) variable directly in the working memory. In other words, before implementing the use and store operations on a variable, you must first The assign and load operations have been performed.

  • A variable can only be locked by one thread at the same time, but the lock operation can be repeated by the same thread multiple times. After the lock is executed multiple times, the variable will be unlocked only after the same number of unlock operations are performed.

  • If the lock operation is performed on a variable, the value of the variable in the working memory will be cleared. Before the execution engine uses the variable, the load or assign operation needs to be re-executed to initialize the value of the variable.

  • If a variable is not previously locked by a lock operation, it is not allowed to perform an unlock operation on it, nor to unlock a variable that is locked by another thread.

review

1. The Java memory model is a specification that specifies how and when different threads can see values ​​written to shared variables by other threads and how to synchronize access to shared variables when necessary.

2. The Java memory model requires that call stacks and local variables are stored on the thread stack, and objects are stored on the heap. Communication between threads must go through main memory.

3. Defines eight synchronization operations and the rules that need to be followed when using these eight operations.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325851966&siteId=291194637