编程知识 cdmana.com

Today, let's talk about the memory model of Java

  1. summary    Multitasking and high concurrency is one of the important indexes to measure the ability of a computer processor . Generally measure the performance of a server , Use transactions per second (Transactions Per Second,TPS) This index can explain the problem , It represents the average number of requests that the server can respond to in a second , and TPS Value is closely related to the concurrent ability of a program . In the discussion Java Before the thread model and memory model , Let's briefly introduce the efficiency and consistency of the hardware .

2. Efficiency and consistency of hardware    Because there are several orders of magnitude gap between the computer's storage device and the processor's computing power , So modern computer systems have to add a layer of read-write speed as close as possible to the processor speed of the cache (cache) As a buffer between memory and processor : Copies the data that the operation needs to use into the cache , Let's make it fast , When the operation is finished, it is synchronized back into memory from the cache so that the processor does not have to wait for slow memory reads and writes .    Cache based storage interaction solves the speed conflict between processor and memory , But a new problem has been introduced : Cache consistency (Cache Coherence). In a multiprocessor system , Each processor has its own cache , And they share the same main memory , As shown in the figure below : Multiple processor operations involve the same main memory , We need a protocol to guarantee the consistency of data , Such agreements are MSI、MESI、MOSI And Dragon Protocol etc. .Java The memory access operations defined in the memory model of virtual machine are comparable to the cache access operations of hardware , It will be introduced later Java Memory model . Insert picture description here

   besides , In order to make full use of the computing units in the processor , The processor may shuffle the input code (Out-Of-Order Execution) Optimize , The processor recombines the results of the out of order code after the calculation , Ensure the accuracy of the results . Similar to processor shuffle execution optimization ,Java There are similar instructions reordering in the immediate compiler of virtual machine (Instruction Recorder) Optimize .

3.Java Memory model    Definition Java The memory model is not an easy thing to do , The model must be well defined , To make Java There is no ambiguity in concurrent operations ; however , It has to be loose enough , So that the implementation of the virtual machine can have enough free space to take advantage of the various features of the hardware ( register 、 Cache, etc ) For better execution speed . After a long time of verification and repair , stay JDK1.5 After the release of ,Java The memory model is already mature and perfect .

3.1 Main memory and working memory   Java The main goal of the memory model is to define access rules for the variables in the program , The low-level details of storing variables into and out of memory in a virtual machine . The variables here and Java The variables are not the same when programming , Includes instance fields 、 Static fields and the elements that make up the array object , However, local variables and method parameters are not included , The latter is private to the thread , Will not be Shared .

  Java The memory model specifies that all variables are stored in main memory , Each thread has its own working memory ( It can be compared with the cache of the processor mentioned above ), The working memory of the thread holds the copy of the variables used by the thread to the main memory copy , All operations of a thread on a variable ( Read 、 assignment ) All must be done in working memory , Variables in main memory cannot be read or written directly . Different threads cannot directly access variables in each other's working memory , The transfer of variable values between threads needs to be completed in main memory , Threads 、 The interaction between main and working memory is shown in the following figure , It's very similar to the picture above . Insert picture description here

The main memory here 、 Working memory and Java Memory area Java Pile up 、 Stack 、 Method area is not the same level of memory partition .

3.2 Inter memory interaction    About the specific interaction protocol between main memory and working memory , That is, how to copy a variable from main memory to working memory 、 How to synchronize from working memory to main memory ,Java The memory model defines the following eight operations to complete :

lock( lock ): A variable acting on main memory , Identifies a variable as a thread exclusive state . unlock( Unlock ): Operates on the main memory variable , Release a variable that is locked , Freed variables can be locked by other threads . read( Read ): Operates on the main memory variable , Transfers a variable value from main memory to the thread's working memory , For subsequent load The action to use load( load ): A variable acting on working memory , It is the read The operation places the values of the variables obtained from main memory into a copy of the variables in working memory . use( Use ): A variable acting on working memory , Passes the value of a variable in working memory to the execution engine , This is done whenever the vm gets a bytecode instruction that requires the value of the variable to be used . assign( assignment ): A variable acting on working memory , It assigns a value received from the execution engine to a variable in the working memory , This is done whenever the vm receives a bytecode instruction that assigns a value to a variable . store( Storage ): A variable acting on working memory , Transfers the value of a variable in working memory to main memory , For subsequent write The operation of . write( write in ): A variable acting on main memory , It is the store Operations are passed from the value of a variable in working memory to the variable in main memory .    If you want to copy a variable from main memory to working memory , You need to follow the order read and load operation , If you synchronize variables from working memory back to main memory , You have to do it sequentially store and write operation .Java The memory model only requires that the above operations be performed in order , There is no guarantee that the execution must be continuous . That is to say read and load Between ,store and write Other instructions can be inserted between , As for variables in main memory a、b When doing an interview , The possible order is read a,read b,load b, load a.Java The memory model also specifies when the eight basic operations described above are performed , The following rules must be met :

Don't allow read and load、store and write One of the operations occurs separately A thread is not allowed to discard its nearest assign The operation of , That is, variables must be synchronized to main memory after they have changed in working memory . A thread is not allowed for no reason ( It didn't happen assign operation ) Synchronize data from working memory back to main memory . A new variable can only be created in main memory , It is not allowed to use an uninitialized one directly in working memory (load or assign) The variable of . That is to say, to implement a variable use and store Before the operation , Must be executed first assign and load operation . Only one thread is allowed to work on a variable at a time lock operation ,lock and unlock They have to come in pairs If you execute on a variable lock operation , Will empty the value of this variable in working memory , The variable needs to be reexecuted before the execution engine can use it load or assign The operation initializes the value of the variable If a variable is not previously lock Locking operation , It is not allowed to be executed unlock operation ; I'm not allowed to go unlock A variable that is locked by another thread . Execute on a variable unlock Before the operation , You must first synchronize this variable to main memory ( perform store and write operation ). 3.3 Reorder    In order to improve performance when executing programs , Compilers and processors often reorder instructions . There are three types of reordering :

Compiler optimized reordering . The compiler does not change the semantics of a single threaded program , You can rearrange the execution order of statements . Instruction level parallel reordering . Modern processors use instruction level parallelism to execute multiple instructions in an overlapping way . If there is no data dependency , The processor can change the execution order of machine instructions corresponding to statements . Reordering of memory system . Because the processor uses cache and read-write buffer , This makes loading and storage operations appear to be out of order . from Java The sequence of instructions from the source code to the final actual execution , There are three sorts of reordering :  Insert picture description here

To ensure the visibility of memory ,Java The compiler inserts a memory barrier instruction in place of the generated instruction sequence to prevent a particular type of processor reordering .Java The memory model divides memory barriers into LoadLoad、LoadStore、StoreLoad and StoreStore Four kinds of :  Insert picture description here

3.4 Synchronization mechanism Introduce volatile、synchronized and final

3.5 Atomicity 、 Visibility and order Introduce three features

版权声明
本文为[osc_ forty-eight million eight hundred and thirteen thousand fo]所创,转载请带上原文链接,感谢
https://cdmana.com/2020/12/20201224133939767q.html

Scroll to Top