JVM | Java memory model

Source: Internet
Author: User
Tags flushes

Objective

"The World martial arts, only fast not broken", the fire cloud evil God told you the pursuit of the realm of the body, the theory of relativity also tells you that when you move faster than the speed of light or even faster, you can easily go to poetry and distance, Nao, visit Saturn, wandering around; when a single-core computer increases performance from the generation to the other, the computational power is faster Even the Olympic Games are seeking "faster, higher, stronger", it seems that "fast" to people have innate temptation. So "fast rhythm and the past slow life only enough to love a person", you have what kind of thinking, sorry ~ here is not discussed. In fact, people are constantly squeezing computing tools and the boss's ability to squeeze employees is just as pleasurable. Since it is pressed, one day may be nearly squeezed out of oil, what to do?

This does not, the single core CPU frequency can not be unlimited growth, Intel boss to kneel. Again want to improve performance, so the CPU into the multi-core era, multiple processors work together. What, work together? Elementary School study class Most can wound up is you, high school is not the tube is you, in fact, many times is not the pursuit of a plus a more than two, but a plus one not less than one, the more the more the more messy, the more the more annoying, a truth, increase the number of CPUs is not a simple plus one, the more variables, the more Talented people are more suitable for managers, of course, with adequate and sophisticated algorithms of the operating system to work together good computer.

Multitasking is almost an essential feature in modern computer operating systems. In many cases, let the computer do a few things at the same time, not only because the computer's computing power is powerful, but also a very important reason is that the computer's computing speed and its storage and communication subsystem speed gap is too large. Computer storage devices and processors have several orders of magnitude difference, so modern computers have to add a layer of read and write speed as close as possible to the processor speed of the cache as a buffer between memory and processor, this is the solution of the idea is buffering technology.
Cache-based storage interaction solves the speed contradiction between processor and memory, but also brings a higher complexity to the computer system, and introduces new problems: Cache consistency. In multiprocessor systems, each processor has its own cache and shares the same main memory.

Processor Memory Conceptual model

Java Memory Conceptual model

Compilers and processors
    • With the same goal, to maximize the degree of parallelism without changing the results of the program execution.

    • The processor does not change the order of execution of the two operations that exist for data dependencies.

    • The processor guarantees that the reordering of single-threaded threads does not change execution results.

    • The more performance-seeking processors, the weaker the memory model is, the less constrained, and the more optimized it is to improve performance.

    • The compiler does not alter the order of execution of the two operations that exist for data dependencies.

    • The compiler guarantees that the reordering of single-threaded threads does not change the execution result.
Re-order
    • Processor reordering

In addition to increasing the cache, in order to make the operating unit within the processor as fully utilized as possible, the processor may perform a random execution optimization of the input code, and the processor will reorganize the structure of the order execution after the calculation.

    • Data dependencies

If two operations access the same variable, and one of the two operations is a write operation, there is a data dependency between the two operations.
1) After writing this variable, read the variable again;
2) After writing this variable, write the variable again;
3) After reading this variable, write the variable again;
In the above 3 cases, as long as the execution order of two operations is re-ordered, the execution result will be changed.

    • As-if-serial

The semantics are: the execution results of a single-threaded process cannot be changed, regardless of how the compiler and processor are reordered in order to improve the degree of parallelism.

    • Happens-before

Happens-before requires that the reordering of prohibitions be divided into two categories:
1) will change the reordering of the results of the program execution.
The JMM processing policy requires that the compiler and processor must disallow such reordering.
2) does not change the reordering of program execution results.
The JMM processing policy allows this reordering of compilers and processors.

Rule definition:
1) Program Order rules: Each action in a thread, happens-before any subsequent operation of that thread.
2) Monitor lock rule: Unlock a lock, happens-before to the locking of the lock later on.
3) Volatile variable rule: write to a volatile field, happens-before to any subsequent reading of this volatile field.
4) Transitivity: If a happens-before B, and B happens-before C, then a Happens-before c.
5) Start () rule: If thread A performs an action Threadb.start () to start thread B, then the Threadb.start () operation of the A thread happens-before any action in thread B.
6) Join () rule: If thread A performs an operation Thread.Join () and returns successfully, any action in thread B happens-before the successful return of thread A from the Thread.Join () operation.

    • Summary

1) as-if-serial semantics guarantees that the execution result of a single-threaded program is not changed, and that the happens-before relationship guarantees that the execution results of correctly synchronized multithreaded programs are not changed.
2) As-if-serial semantic creation single-threaded program fantasy: Single-threaded programs are executed in the order of the program; Happens-before relationships Create multithreaded Programs Mirage: The correct synchronization of multithreaded programs is performed in the order specified by Happens-before.

Java memory model
    • Java Memory Model specification defines the competition for data:
      Write a variable in one thread, read the same variable in another thread, and write and read are not sorted by synchronization.

    • JMM allows compilers and processors to be optimized as long as they do not change the results of program execution, including single-threaded programs and correctly synchronized multithreaded procedures.

    • The common processor memory model is weaker than JMM, and when the Java compiler generates bytecode, it inserts a memory barrier at the appropriate place in the execution instruction sequence to limit the processor's reordering. The various processor memory models are different in strength, and the number and type of memory barriers that JMM inserts in different processors are not the same.

    • Inter-memory interaction operations:

1) Lock: A variable that acts on the main memory and identifies a variable as a thread-exclusive state.
2) Unlock (unlocked): A variable that acts on the main memory, frees a variable that is locked, and the unlocked variable can be locked by another thread.
3) Read: A variable that acts on the main memory, transferring the value of a variable from main memory to the working memory of the thread for subsequent load operations to use.
4) Load: A variable that acts on the working memory and puts the value of the variable that the read operation obtains from main memory into a variable copy of the working memory.
5) Use: A variable acting on the working memory, passing the value of a variable in the working memory to the execution engine, which will be performed whenever the virtual opportunity is to a byte-code instruction of the value of the variable to be used.
6) Assign (Assignment): A variable that acts on the working memory, assigns a variable that is received from the execution engine to the working memory, and performs this operation whenever the virtual opportunity is given to a byte-code instruction that assigns a value to a variable.
7) Store: A variable that acts on the working memory, transferring the value of a variable in the working memory to the main memory for subsequent write operations to use.
8) Write (write): A variable that acts on the main memory, putting the store operation flush the value of the variable obtained in the working memory into the main memory variable.

    • The rules that must be met to perform the 8 basic operations mentioned above:

1) does not allow one of the read and load, store, and write operations to appear separately, that is, a variable is not allowed to read from the main memory but the working memory is not accepted, or from the working memory initiated writeback but the main memory is not acceptable.
2) does not allow a thread to discard its most recent assign operation, that is, the variable must be synchronized back to main memory after it has changed in working memory.
3) A thread is not allowed to synchronize data from the working memory of the thread back to main memory for no reason (no assign operation has occurred).
4) A new variable can only be "born" in main memory and not be allowed to use a non-initialized variable directly in working memory, in other words, the Assign and load operations must be performed before a variable is implemented with a use, store operation.
5) A variable is allowed only one thread to lock it at the same time, but the lock operation can be repeated multiple times by the same thread, and after performing the lock multiple times, the variable will be unlocked only if the same number of unlock operations are performed.
6) If you perform a lock operation on a variable, that will empty the value of the variable in the working memory, and the load or assign operation initializes the value of the variable before the execution engine uses the variable.
7) If a variable is not locked by the lock operation beforehand, it is not allowed to perform a unlock operation on it, nor is it allowed to unlock a variable that is locked by another thread.
8) before performing a unlock operation on a variable, you must first synchronize this variable back into main memory.

Memory Semantics of Locks

Semantic:

    • When a thread releases a lock, JMM flushes the shared variable in the local memory corresponding to that thread into main memory.
    • When a thread acquires a lock, JMM will place the local memory corresponding to that thread as invalid.

Thread A releases a lock, essentially a thread A sends a message (modified by thread A to the shared variable) to a thread that is going to acquire the lock.
Thread B acquires a lock, in essence, thread B receives a message from a previous thread (modified to a shared variable before releasing the lock).
Thread A releases the lock, and then thread B acquires the lock, which is essentially thread A sends a message to thread B through main memory.

Realize:
See AQS and so on.

Volatile memory semantics

Semantic:

    • When a volatile variable is written, jmm flushes the shared variable value in the local memory corresponding to that thread to the main memory.
    • When reading a volatile variable, JMM will set the local memory corresponding to that thread to be invalid.

Thread A writes a volatile variable, essentially a message that thread A sends (its modifications to a shared variable) to a thread that is going to read the volatile variable.
Thread B reads a volatile variable, essentially thread B receives a message from a previous thread (modified to a shared variable before writing the volatile variable).
Thread A writes a volatile variable, and then thread B reads the volatile variable, which is essentially a thread A sends a message to thread B through main memory.

JMM implementation:

    • Insert a storestore barrier in front of each volatile write operation.
    • Insert a storeload barrier behind each volatile write operation.
    • Insert a loadload barrier in front of each volatile read operation.
    • Insert a loadstore barrier behind each volatile read operation.

Performance:

    • Visibility: Reading a volatile variable, you can always see the last write to this volatile variable by any thread.
    • Atomicity: The reading and writing of any single volatile variable is atomic, but a conforming operation like volatile++ does not have atomicity.
Final Memory semantics

For the final domain, the compiler and processor are subject to two reordering rules:

    • Writing to a final field within the constructor, and then assigning a reference to the constructed object to a reference variable, cannot be reordered between the two operations.
    • The first time you read a reference to an object that contains a final field, and the final field is then first read, the two operations cannot be reordered.

Compiler final semantics are implemented specifically:

    • A reorder rule that writes a final field requires the compiler to insert a storestore barrier before the constructor return after the final field is written.
    • The re-collation of the Read final field requires the compiler to insert a loadload barrier before the operation of the final domain.
public class FinalExample {    int i;    final int j;    static FinalExample obj;    public FinalExample(){        i = 1;        j = 2;        // final域 StoreStore屏障 在这里        // 确保构造函数return前 final域 j=2 完成    }    public static void write(){        obj = new FinalExample();    }    public static void reader(){        FinalExample object = obj;        int a = object.i;        // final域 LoadLoad屏障 在这里        // 确保初次读对象包含的final域前 读对象引用完成        int b = object.j;    }}
Summarize
    • Both processors and compilers expect to maximize the degree of parallelism without changing the results of the program execution.
    • Both the processor and the compiler may perform an optimization of the input code in order to make full use of the arithmetic unit.
    • Neither the processor nor the compiler alters the order of execution of the two operations in which data dependencies exist.
    • Both processors and compilers ensure that the reordering of single-threaded threads does not alter the execution results.
    • Processor memory models are weaker than JMM and are more biased towards performance considerations.
    • JMM Shields the cross-platform processor from different levels of command reordering for different processors to ensure the correct semantics as much as possible.
    • Seeing through as-if-serial semantics and happens-before relationships can help programmers understand concurrent programming in depth and edit efficient, robust code.

Reference "in-depth understanding of Java Virtual Machines", "The Art of Java concurrent programming"

JVM | Java memory model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.