Java内存模型
内存模型:
在JSR-133: JavaTM Memory Model and Thread Specification(http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf)中式这么定义的:
JSR-133: JavaTM Memory Model and Thread Specification 写道
What is a Memory Model?
A memory model describes, given a program and an execution trace of that program, whether
the execution trace is a legal execution of the program. For the Java programming language, the
memory model works by examining each read in an execution trace and checking that the write
observed by that read is valid according to certain rules.
The memory model describes possible behaviors of a program. An implementation is free to
produce any code it likes, as long as all resulting executions of a program produce a result that
can be predicted by the memory model. This provides a great deal of freedom to perform a
myriad of code transformations, including the reordering of actions and removal of unnecessary
synchronization.
A high level, informal overview of the memory model shows it to be a set of rules for when
writes by one thread are visible to another thread. Informally, a read r can usually see the value
of any write w such that w does not happen-after r and w is not seen to be overwritten by another
write w
0
(from r’s perspective).
When we use the term “read” in this memory model, we are only referring to actions that
read fields or array elements. The semantics of other operations, such as reads of array lengths,
executions of checked casts, and invocations of virtual methods, are not directly affected by data
races. The JVM implementation is responsible for ensuring that a data race cannot cause incorrect
behavior such as returning the wrong length for an array or having a virtual method invocation
cause a segmentation fault.
The memory semantics determine what values can be read at every point in the program. The
actions of each thread in isolation must behave as governed by the semantics of that thread, with
the exception that the values seen by each read are determined by the memory model. When we
refer to this, we say that the program obeys intra-thread semantics.
A memory model describes, given a program and an execution trace of that program, whether
the execution trace is a legal execution of the program. For the Java programming language, the
memory model works by examining each read in an execution trace and checking that the write
observed by that read is valid according to certain rules.
The memory model describes possible behaviors of a program. An implementation is free to
produce any code it likes, as long as all resulting executions of a program produce a result that
can be predicted by the memory model. This provides a great deal of freedom to perform a
myriad of code transformations, including the reordering of actions and removal of unnecessary
synchronization.
A high level, informal overview of the memory model shows it to be a set of rules for when
writes by one thread are visible to another thread. Informally, a read r can usually see the value
of any write w such that w does not happen-after r and w is not seen to be overwritten by another
write w
0
(from r’s perspective).
When we use the term “read” in this memory model, we are only referring to actions that
read fields or array elements. The semantics of other operations, such as reads of array lengths,
executions of checked casts, and invocations of virtual methods, are not directly affected by data
races. The JVM implementation is responsible for ensuring that a data race cannot cause incorrect
behavior such as returning the wrong length for an array or having a virtual method invocation
cause a segmentation fault.
The memory semantics determine what values can be read at every point in the program. The
actions of each thread in isolation must behave as governed by the semantics of that thread, with
the exception that the values seen by each read are determined by the memory model. When we
refer to this, we say that the program obeys intra-thread semantics.
来自Synchronization and the Java Memory Model(http://gee.cs.oswego.edu/dl/cpj/jmm.html)的一张图片:
Java内存模型定义了线程如何通过内存进行交互。
http://www.cs.umd.edu/~pugh/java/memoryModel/ 写道
The Java Memory Model defines how threads interact through memory.
主内存
工作内存
线程执行时,对变量的操作抽象为action,那么这个action通过一个元组< t, k, v, u >进行描述。
t表示线程执行的action
k表示线程执行的action的类型
v表示线程执行的action所涉及到的变量或对象监视器
https://docs.oracle.com/javase/specs/jls/se12/html/jls-17.html#jls-17.4.2 写道
For lock actions, v is the monitor being locked; for unlock actions, v is the monitor being unlocked.
If the action is a (volatile or non-volatile) read, v is the variable being read.
If the action is a (volatile or non-volatile) write, v is the variable being written.
u表示线程执行的action的唯一标识符(it's arbitrary)If the action is a (volatile or non-volatile) read, v is the variable being read.
If the action is a (volatile or non-volatile) write, v is the variable being written.
https://docs.oracle.com/javase/specs/jls/se12/html/jls-17.html#jls-17.4.2 写道
An external action tuple contains an additional component, which contains the results of the external action as perceived by the thread performing the action. This may be information as to the success or failure of the action, and any values read by the action.
Parameters to the external action (e.g., which bytes are written to which socket) are not part of the external action tuple. These parameters are set up by other actions within the thread and can be determined by examining the intra-thread semantics. They are not explicitly discussed in the memory model.
In non-terminating executions, not all external actions are observable. Non-terminating executions and observable actions are discussed in §17.4.9.
Parameters to the external action (e.g., which bytes are written to which socket) are not part of the external action tuple. These parameters are set up by other actions within the thread and can be determined by examining the intra-thread semantics. They are not explicitly discussed in the memory model.
In non-terminating executions, not all external actions are observable. Non-terminating executions and observable actions are discussed in §17.4.9.
https://docs.oracle.com/javase/specs/jls/se12/html/jls-17.html#jls-17.4.2 写道
An action a is described by a tuple < t, k, v, u >, comprising:
t - the thread performing the action
k - the kind of action
v - the variable or monitor involved in the action.
For lock actions, v is the monitor being locked; for unlock actions, v is the monitor being unlocked.
If the action is a (volatile or non-volatile) read, v is the variable being read.
If the action is a (volatile or non-volatile) write, v is the variable being written.
u - an arbitrary unique identifier for the action
An external action tuple contains an additional component, which contains the results of the external action as perceived by the thread performing the action. This may be information as to the success or failure of the action, and any values read by the action.
Parameters to the external action (e.g., which bytes are written to which socket) are not part of the external action tuple. These parameters are set up by other actions within the thread and can be determined by examining the intra-thread semantics. They are not explicitly discussed in the memory model.
In non-terminating executions, not all external actions are observable. Non-terminating executions and observable actions are discussed in §17.4.9.
t - the thread performing the action
k - the kind of action
v - the variable or monitor involved in the action.
For lock actions, v is the monitor being locked; for unlock actions, v is the monitor being unlocked.
If the action is a (volatile or non-volatile) read, v is the variable being read.
If the action is a (volatile or non-volatile) write, v is the variable being written.
u - an arbitrary unique identifier for the action
An external action tuple contains an additional component, which contains the results of the external action as perceived by the thread performing the action. This may be information as to the success or failure of the action, and any values read by the action.
Parameters to the external action (e.g., which bytes are written to which socket) are not part of the external action tuple. These parameters are set up by other actions within the thread and can be determined by examining the intra-thread semantics. They are not explicitly discussed in the memory model.
In non-terminating executions, not all external actions are observable. Non-terminating executions and observable actions are discussed in §17.4.9.
action在JSR-133: JavaTM Memory Model and Thread Specification(http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf)中被称为Inter-thread Action
Inter-thread actions
JSR-133: JavaTM Memory Model and Thread Specification 写道
Inter-thread actions include reads and writes of
shared variables and synchronization actions, such as locking or unlocking a monitor, reading or
writing a volatile variable, or starting a thread. Also included are actions that interact with the
external world (external actions), and actions that cause a thread to go into an infinite loop (thread
divergence actions). For more information on these actions, consult Section 7.1.
shared variables and synchronization actions, such as locking or unlocking a monitor, reading or
writing a volatile variable, or starting a thread. Also included are actions that interact with the
external world (external actions), and actions that cause a thread to go into an infinite loop (thread
divergence actions). For more information on these actions, consult Section 7.1.
包括:
1、reads and writes of shared variables
2、synchronization actions, such as locking or unlocking a monitor, reading or writing a volatile variable, or starting a thread
3、interact with the external world (external actions)
4、cause a thread to go into an infinite loop (thread divergence actions)
JSR-133: JavaTM Memory Model and Thread Specification 写道
Every inter-thread action is associated with information about the execution of that action. All
actions are associated with the thread in which they occur and the program order in which they
occur within that thread. Additional information associated with an action include:
---------------------------------------------------------------------------------------------
|write | The variable written to and the value written. |
|read | The variable read and the write seen (from this, we can determine the value seen).|
|lock | The monitor which is locked. |
|unlock | The monitor which is unlocked. |
---------------------------------------------------------------------------------------------
For brevity’s sake, we usually refer to inter-thread actions as simply actions.
actions are associated with the thread in which they occur and the program order in which they
occur within that thread. Additional information associated with an action include:
---------------------------------------------------------------------------------------------
|write | The variable written to and the value written. |
|read | The variable read and the write seen (from this, we can determine the value seen).|
|lock | The monitor which is locked. |
|unlock | The monitor which is unlocked. |
---------------------------------------------------------------------------------------------
For brevity’s sake, we usually refer to inter-thread actions as simply actions.
Synchronization Actions
JSR-133: JavaTM Memory Model and Thread Specification 写道
Synchronization actions include locks, unlocks, reads of and writes
to volatile variables, actions that start a thread, and actions that detect that a thread is done. Any
action that is the start or end-point of a synchronizes-with edge is a synchronization action. Such
actions are listed in more detail below under happens-before edges.
to volatile variables, actions that start a thread, and actions that detect that a thread is done. Any
action that is the start or end-point of a synchronizes-with edge is a synchronization action. Such
actions are listed in more detail below under happens-before edges.
Happens-Before
Synchronizes-With
同步操作(Synchronization actions)也会产生Happens-Before,我们称之为Synchronizes-With
lock,unlock,read,load,use,assign,store,write
内存屏障
LoadLoad屏障
StoreStore屏障
LoadStore屏障
StoreLoad屏障
http://gee.cs.oswego.edu/dl/jmm/cookbook.html 写道
LoadLoad Barriers
The sequence: Load1; LoadLoad; Load2
ensures that Load1's data are loaded before data accessed by Load2 and all subsequent load instructions are loaded. In general, explicit LoadLoad barriers are needed on processors that perform speculative loads and/or out-of-order processing in which waiting load instructions can bypass waiting stores. On processors that guarantee to always preserve load ordering, the barriers amount to no-ops.
StoreStore Barriers
The sequence: Store1; StoreStore; Store2
ensures that Store1's data are visible to other processors (i.e., flushed to memory) before the data associated with Store2 and all subsequent store instructions. In general, StoreStore barriers are needed on processors that do not otherwise guarantee strict ordering of flushes from write buffers and/or caches to other processors or main memory.
LoadStore Barriers
The sequence: Load1; LoadStore; Store2
ensures that Load1's data are loaded before all data associated with Store2 and subsequent store instructions are flushed. LoadStore barriers are needed only on those out-of-order procesors in which waiting store instructions can bypass loads.
StoreLoad Barriers
The sequence: Store1; StoreLoad; Load2
ensures that Store1's data are made visible to other processors (i.e., flushed to main memory) before data accessed by Load2 and all subsequent load instructions are loaded. StoreLoad barriers protect against a subsequent load incorrectly using Store1's data value rather than that from a more recent store to the same location performed by a different processor. Because of this, on the processors discussed below, a StoreLoad is strictly necessary only for separating stores from subsequent loads of the same location(s) as were stored before the barrier. StoreLoad barriers are needed on nearly all recent multiprocessors, and are usually the most expensive kind. Part of the reason they are expensive is that they must disable mechanisms that ordinarily bypass cache to satisfy loads from write-buffers. This might be implemented by letting the buffer fully flush, among other possible stalls.
内存屏障相关指令参考另一篇文章:https://lobin.iteye.com/blog/2440503
The sequence: Load1; LoadLoad; Load2
ensures that Load1's data are loaded before data accessed by Load2 and all subsequent load instructions are loaded. In general, explicit LoadLoad barriers are needed on processors that perform speculative loads and/or out-of-order processing in which waiting load instructions can bypass waiting stores. On processors that guarantee to always preserve load ordering, the barriers amount to no-ops.
StoreStore Barriers
The sequence: Store1; StoreStore; Store2
ensures that Store1's data are visible to other processors (i.e., flushed to memory) before the data associated with Store2 and all subsequent store instructions. In general, StoreStore barriers are needed on processors that do not otherwise guarantee strict ordering of flushes from write buffers and/or caches to other processors or main memory.
LoadStore Barriers
The sequence: Load1; LoadStore; Store2
ensures that Load1's data are loaded before all data associated with Store2 and subsequent store instructions are flushed. LoadStore barriers are needed only on those out-of-order procesors in which waiting store instructions can bypass loads.
StoreLoad Barriers
The sequence: Store1; StoreLoad; Load2
ensures that Store1's data are made visible to other processors (i.e., flushed to main memory) before data accessed by Load2 and all subsequent load instructions are loaded. StoreLoad barriers protect against a subsequent load incorrectly using Store1's data value rather than that from a more recent store to the same location performed by a different processor. Because of this, on the processors discussed below, a StoreLoad is strictly necessary only for separating stores from subsequent loads of the same location(s) as were stored before the barrier. StoreLoad barriers are needed on nearly all recent multiprocessors, and are usually the most expensive kind. Part of the reason they are expensive is that they must disable mechanisms that ordinarily bypass cache to satisfy loads from write-buffers. This might be implemented by letting the buffer fully flush, among other possible stalls.
相关推荐
综上所述,JVM和Java内存模型是Java开发者必须掌握的核心知识。通过深入学习这两部分,你可以更好地理解和优化Java程序的运行效率,提升系统的稳定性和性能。阅读"JVM的内存机制介绍.pdf"和"JVM_工作原理.pptx"将为...
Java内存模型(JMM)确保了多线程环境下数据的一致性和可见性。主要概念包括主内存、工作内存、 volatile、synchronized和final关键字。volatile能确保变量对所有线程可见,而synchronized则提供了互斥访问,确保...
2. JVM内存模型:JVM内存模型定义了内存中各个部分的关系,以及在多线程环境下如何共享和分配内存。Java内存模型(JMM)规定了线程对共享变量的可见性和有序性,它通过主内存和工作内存的概念来实现多线程之间的协作...
可以先看我的博客在下载,...增加高速缓存;为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对代码进行乱序执行优化,处理器会在计算机之后将乱序执行的结果重组,保证该结果与顺序执行结果是一致的
Java内存模型,简称JMM(Java Memory Model),是Java编程语言规范的一部分,它定义了程序中各个线程如何访问和修改共享变量,以及如何确保数据的一致性。深入理解Java内存模型对于编写高效的并发程序至关重要。本文...
Java内存模型(JMM)是Java虚拟机(JVM)的一部分,它定义了程序中不同变量如何交互,特别是在多线程环境下。JMM确保了在各种硬件和操作系统平台上,Java程序的行为具有一致性和可预测性。Java内存模型的主要目标是...
JVM内存模型是Java虚拟机的核心组件之一,它直接影响着Java应用程序的性能和可靠性。本文将深入剖析JVM内存模型的结构和工作机理,并讨论如何优化JVM参数以提高Java应用程序的性能。 一、JVM内存模型结构 JVM内存...
### JVM内存模型 #### 堆内存(Heap) 堆是JVM管理的最大块内存区域,用于存储对象实例。堆被划分为新生代和老年代,其中新生代又细分为Eden区和两个Survivor区(S0和S1)。对象首先在Eden区创建,经过几次GC后会被移动...
### Java 虚拟机JVM内存模型知识点 #### 1. JVM概述 ##### 1.1 Java的特性与JVM的应用 Java语言的特性包括跨平台性、面向对象、安全性等。JVM是Java程序能够跨平台运行的关键,它负责将Java源代码转换成与平台无关...
### JVM原理、内存模型、性能调优 ...综上所述,理解JVM的基本原理、掌握内存模型和学会合理的性能调优策略对于开发高效稳定的Java应用程序至关重要。希望本教程能够帮助大家更好地理解和掌握JVM相关的知识和技术。
Java内存模型(Java Memory Model,简称JMM)是Java虚拟机(JVM)规范中定义的一种内存模型,它涉及了线程之间共享变量的可见性问题。在并发编程中,理解Java内存模型对于编写正确的多线程程序至关重要。 首先,...
Java内存模型(JMM)与JVM内存结构不同,它是针对多线程环境下内存访问的抽象模型。JMM确保在多线程环境下,共享变量的读写操作具有正确的顺序和可见性,通过volatile、synchronized等关键字来实现这一目标。JMM关注...
这些文档如"Java内存模型.docx"、"Java内存模型2.docx"、"深入Java核心 Java内存分配原理精讲.docx"、"java内存模型.pdf"将深入探讨这些概念,帮助开发者更深入地理解Java内存模型及其在实际编程中的应用。...
JVM的内存模型包括堆、栈、方法区、本地方法栈和程序计数器等,这些区域各自承担着不同的职责,如存储对象实例、管理方法调用等。JVM的垃圾回收机制也是其一大特点,自动管理内存,避免了程序员手动进行内存管理。 ...
JVM内存模型是Java虚拟机(JVM)中的一种内存管理机制,它将内存区分为永久区内存(Permanent space)和堆内存(heap space)两大块。永久区内存用于存放加载的Class类级对象,如class本身、method、field等等,而堆...
java技术面试必问:JVM-内存模型讲解 本文将详细介绍Java技术面试中必问的JVM内存模型讲解。Java程序的执行过程包括java文件编译、类加载、字节码执行等步骤。在整个加载过程中,JVM使用一段空间来存储程序执行期间...
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)的一部分,用于规定程序中的各种变量(包括实例字段、静态字段和数组元素等)在多个线程共享内存中的读写行为。JMM的主要目的是确保所有线程能够看到一致...
Java内存模型是Java平台的核心概念之一,它定义了Java程序中各种变量的访问规则以及如何在运行时分配内存区域给对象。Java内存模型的深入分析对于编写高性能的Java应用程序至关重要,本文将详细探讨Java内存模型的...
Java内存模型(JVM Memory Model,简称JMM)是Java平台中的一个重要概念,它定义了程序中各个变量的访问规则,以及在多线程环境下的内存一致性效果。JMM主要解决的是并发环境下不同线程之间如何共享数据以及如何保证...