Java memory model

A brief introduction to the Java memory model

The Java Memory Model is also known as the Java Memory Model, or JMM. The JMM defines how the Java Virtual Machine (JVM) works in computer memory (RAM). The JVM is the entire computer virtual model, so the JMM belongs to the JVM.

The Java memory model is a concurrent model of shared memory, in which threads communicate implicitly through read-write shared variables (instance fields, static fields, and array elements in heap memory). The Java Memory Model (JMM) controls communication between Java threads, determining when writes by one thread to a shared variable are visible to another thread.

JVM main memory vs. working memory

The main goal of the Java memory model is to define the access rules for variables in the program, the low-level details of storing variables (variables shared by threads) into and out of memory in the virtual machine.

In the Java memory model, all variables are stored in the main memory, and each thread has its own working memory. All operations on variables must be carried out in the working memory by the thread, instead of reading or writing variables in the main memory. Working memory here is a JMM abstraction, also known as local memory, which stores copies of shared variables that the thread reads/writes.

Just as each processor kernel has its own cache, each thread in the JMM has its own local memory. Different threads cannot directly access variables in each other’s working memory, and there are generally two ways to communicate between threads, one is through message passing, and the other is shared memory. The communication between Java threads adopts shared memory. The interaction between threads, main memory and working memory is shown in the following figure:

Thread A communicates with thread B through two steps:

Thread A updated in the local memory A Shared variables flushed to main memory thread B to the main memory to read before the thread A Shared variables has been updated Here of main memory, working memory and the Java heap, stack, method of the area of the Java memory area is not the same level of memory, such as the two are basically has nothing to do, If the two have to be closely related, the definitions of variables, main memory, and working memory refer primarily to the object instance data part of the Java heap, while working memory corresponds to a portion of the virtual machine stack.

JMM data atom manipulation

Read: reads data from main memory load: writes data from main memory to working memory use: reads data from working memory to compute assign: reassigns the calculated values to the working memory store: Write (write) : assigns the value of a variable in the store past to a variable in the main memory lock: Locks a variable in the main memory and identifies it as a thread-exclusive state UNLOCK: Unlocks a variable in the main memory. After it is unlocked, other threads can lock it

public class VolatileVisibilityTest { private static volatile boolean initFlag = false; public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { System.out.println("waiting data..." ); while (! initFlag) { } System.out.println("====================success"); } }).start(); Thread.sleep(2000); new Thread(new Runnable() { @Override public void run() { prepareDate(); } }).start(); } public static void prepareDate() { System.out.println("preparing data..." ); initFlag = true; System.out.println("prepare end..." ); }}Copy the code

Computer caching and cache consistency

Computers use caches between fast cpus and relatively slow storage devices as a buffer between memory and the processor. Copy the data needed for the operation to the cache so that the operation can run quickly. When the operation is finished, it is synchronized from the cache back to memory.

In a multi-processor system (or a single-processor, multi-core system), each processor core has its own cache, and they share the same Main Memory. When the computation tasks of multiple processors all involve the same main memory area, the cache data of each processor may be inconsistent.

Therefore, each processor must follow some protocols when accessing the cache, and operate according to the protocols when reading and writing the cache to maintain the consistency of the cache.

MESI cache consistency protocol: Multiple cpus read the same data from main memory into their respective tell caches. When one OF the cpus modifies the data in the cache, the data is immediately synchronized to main memory. The other cpus use bus sniffing to sense the change and invalidate their own caches.

How volatile cache visibility is implemented

The underlying implementation is mainly implemented by assembling the lock prefix instruction, which locks the cache of this memory area (cache row lock) and writes back to main memory

2) This write back to memory will cause invalidation of data cached in other cpus. (MESI)

Reorder and happens-before rule

To improve performance, compilers and processors often reorder instructions when executing programs. There are three types of reordering:

Compiler optimized reordering. The compiler can rearrange the execution order of statements without changing the semantics of a single-threaded program. Instruction – level parallel reordering. Modern processors use instruction-level Parallelism (ILP) to overlap multiple instructions. If there is no data dependency, the processor can change the execution order of the machine instructions corresponding to the statement. Memory system reordering. Because the processor uses caching and read/write buffers, this makes the load and store operations appear to be out of order. The sequence of instructions from the Java source code to the actual execution goes through one of the following three reorders:

The JMM is a language-level memory model that ensures consistent memory visibility for programmers across compilers and processor platforms by disallowing certain types of compiler reordering and processor reordering. The Java compiler disallows processor reordering by inserting a memory barrier at the appropriate location of the generated instruction sequence (reordering cannot reorder subsequent instructions to the location before the barrier).

happens-before

Starting with JDK5, the Java memory model introduced the concept of happens-before to illustrate memory visibility between operations. If the results of one operation need to be visible to another, there must be a happens-before relationship between the two operations. The two operations mentioned here can be within a thread or between different threads. By “visibility”, I mean that when one thread changes the value of the variable, the new value is immediately visible to other threads.

If A happens-before B, then the Java memory model guarantees the programmer that the result of A’s operation will be visible to B, and that A takes precedence over B in execution order.

The important happens-before rules are as follows:

Procedure order rule: For every action in a thread, happens-before any subsequent action in that thread. Monitor lock rule: The unlocking of a monitor lock, happens-before the subsequent locking of the monitor lock. Volatile variable rule: Writes to a volatile field, happens-before any subsequent reads to that volatile field. Transitivity: If A happens-before B, and B happens-before C, then A happens-before C. Below is the happens-before relationship with the JMM

The last

At the end of the article the author sorted out a lot of information for you! Including the first line of large factory Java interview questions summary + each knowledge point learning thinking guide + a 300 page PDF document Java core knowledge points summary! These are some of the things that the interviewer should ask during the interview. These include basics, Java collections, JVMS, multi-threaded concurrency, Spring principles, microservices, Netty and RPC, Kafka, diaries, design patterns, Java algorithms, databases, Zookeeper, distributed caching, data structures, and more. Welcome to pay attention to the public number: the future has light, receive!