JAVA内存模型后续问题

A更新了本地副本x的值,不会主动刷新到主存中吗,必须等到和B通信时?
  --A线程迟早会把更新过的X值刷新到主内存中,但具体会在什么时候刷新到主内存是不确定的。如果我们使用同步原语(synchronized,volatile和final),那么刷新的时机是确定的。比如,如果A线程释放了锁,它就会刷新本地内存A;接下来如果B线程获取同一个锁,B线程就会到主内存中去读取共享变量的值。此时,B线程就可以读取到A线程对共享变量所做的修改了(即“A线程释放锁--B线程获取锁”可以实现A,B线程之间的通信)。

另外,为什么是A和B通信,而不是B和A通信?
  --这里的通信是指线程之间通过共享变量来沟通。由于共享变量在所有线程之间共享,如果A,B线程之间需要沟通,只需要A线程把写过的共享变量的值刷新到主内存,随后B线程到到主内存中去读取这些共享变量即可。这个过程可以让B线程看到A线程对共享变量锁做的修改,这种线程之间的沟通方式在本文中称之为通信。

在某个方法里面定义了一个数组,这个数组的对其他线程是不可见的,因为每个线程都有自己的独立内存空间,称之为Java方法栈,其生命周期和线程的生命周期一致,至于这个数组存放在哪里,可能是存放当前线程的PC寄存器里,PC寄存器可以利用java的堆内存也可以直接就存放在该PC寄存器的内存空间内。如果是存放在java 的堆内存中,对其他现场是可见的,但是没有线程去使用它,即就是本文所说没有通信,因此还是线程安全的。如果是直接 存放在寄存器内,效率很高。我想这就是线程栈封闭的一部分吧~

对象能否被多个线程共享和它存在哪里没有必然联系。这其实是要分清楚对象与对象的引用的差别。“实例域、静态域和数组元素存储在堆内存中,堆内存在线程之间共享”这句话干脆理解成对象是存储在堆内存中的比较简单。而对象的引用可以理解成一个值,这个值就像是int、char这样的值一样,可以存储在Stack空间中,只不过对象的引用这个值是一个内存地址,而不是像int型的123或者char型的‘V‘。因此,如果是在方法体内调用的一个局部数组如:
void methodA(){
Object[] objects=new Object[]{new Object(),new Object(),new Object()};
}
显然,objects数组引用的3个对象是存在堆内存中的,而objects数组引用本身是存储在stack空间中的。但是,由于一个线程不能直接访问另外一个线程的stack空间,因此上述的数组事实上是无法在多个线程之间共享的。

多线程会导致占用重复的内存空间吗?

回答这个问题首先要弄清究竟什么是工作内存,什么是主内存(指RAM?指Java Heap内存?)。所以,我觉得还是不要去纠结什么是工作内存、什么是主内存。那只是JVM规范为了叙述方便弄出的术语(可能是考虑跨平台吧,我想)。其实,我们只需要弄清楚一点:处理器并不是直接访问RAM(事实上,它也称主内存),而是通过高速缓存(Cache)访问内存。也就是说,从高级语言代码的角度看的一个变量,我们可以理解为它是存在RAM中的。因此对变量的读写操作就是对RAM的读写操作。但是,处理器对我们所谓的读写内存操作实际上是对高速缓存的读写操作。以一个单处理器的系统为例,代码中的一个变量其实是同时占用一份RAM空间和一份高速缓存空间。那么,对于多核处理器的系统而言,这一个变量还是占用一份RAM空间,所不同的是它可能同时占用多份高速缓存空间。而缓存相关性(Cache Coherence)协议则是用来保证高速缓存之间以及高速缓存与RAM之间的数据的一致性。

内存占用主要有3个方面:1)一个线程就是一个对象,对象本身会占用内存空间;2)创建线程(即Thread实例)的时候,JVM会未每个这样的对象(对象本身占用内存)额外分配两个线程调用栈(callstack)所需的内存空间,一个用于跟踪Java方法调用,另一个用于跟踪本地(native)方法调用);3)线程运行过程中可能持有对其它对象的引用,只要这些线程没有终止,那么这些 被引用的对象就无法被垃圾回收。
性能下降,要具体问题具体分析,但是从一般的角度看,可以从上下文切换的角度去分析:一般地,线程数量越多,产生上下文切换就越多,其处理器时间开销也越大。这也就意味着,处理器用于执行应用代码的时间也相对减少。这呈现出来的效果就是应用性能下降。在Java8中可以使用JMC监控下Java应用的上下文切换数量(单位监控时间内的)。

时间: 2024-11-08 18:22:18

JAVA内存模型后续问题的相关文章

深入理解Java内存模型(1 ) -- 基础(转载)

原文地址:http://www.infoq.com/cn/articles/java-memory-model-1 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程之间没有公共状态,线

Java内存模型与垃圾回收

1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法,这个计数器记录正在执行的虚拟机字节码指令的地址,如果执行的是Native方法,这个计算器值为空. Java虚拟机栈:线程私有的,其生命周期和线程一致,每个方法执行时都会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口等信息. 本地方法栈:与虚拟机栈功能类似,只不过虚拟机栈为虚拟机执行J

深入java内存模型(一)

最近本来想深入学习一下java线程,很想知道其中实现的原理,比如线程资源的共享,线程私有空间,以及线程直接的同步控制等.如果能了解它的实现,对于深入学习线程,会有很大的帮助.最近正在看一份<深入java内存模型>的资料.讲的就是java线程方面的实现原理,拿出来分享一下. 说到线程,我们首先想到的是线程的通信.学习操作系统时,线程通信有两种,一种是通过共享内存,另一种是通过消息传递.共享内存属于隐式的通信,线程之间共享一块内存,线程都可以往这块内存写数据,读数据就实现了通信.而消息传递时一个显

深入理解Java内存模型之系列篇[转]

原文链接:http://blog.csdn.net/ccit0519/article/details/11241403 深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. see:命令式编程.函数式编程 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存

Java内存模型知识点小结---《深入理解Java内存模型》(程晓明)读书总结

一.Java内存模型介绍 内存模型的作用范围: 在Java中,所有实例域.静态域和数组元素存放在堆内存中,线程之间共享,下文称之为“共享变量”.局部变量.方法参数.异常处理器等不会在线程之间共享,不存在内存可见性问题,也不受内存模型的影响. 重排序与可见性: 现代编译器在编译源码时会做一些优化处理,对代码指令进行重排序:现代流水线结构的处理器为了提高并行度,在执行时也可能对指令做一些顺序上的调整.重排序包括编译器重排序.指令级并行重排序和内存系统重排序等.一般来说,编译器和处理器在做重排序的时候

深入理解Java内存模型(一)——基础

并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信. 同步是指程序用于控制不同线程之间操作发生相对顺序的机制.在共享内存并发

Java内存模型的历史变迁

转自:http://www.csdn.net/article/2015-05-20/2824722-Java 摘要:本文通过介绍Java的新/旧内存模型,来展示Java技术的历史变迁. 本文通过介绍Java的新/旧内存模型,来展示Java技术的历史变迁. 旧的Java内存模型 Java 使用的是共享内存的并发模型,在线程之间共享变量.Java语言定义了线程模型规范,通过内存模型控制线程与变量的交互,从而实现Java线程之间的通 信.在JDK5之前,Java一直使用的是旧内存模型.如图1所示.变量

修复 Java 内存模型,第 2 部分——Brian Goetz

转自Java并发大师Brain Goetz:http://www.ibm.com/developerworks/cn/java/j-jtp03304/ (中文地址) http://www.ibm.com/developerworks/java/library/j-jtp03304/index.html (英文地址) 在 JSR 133 中 JMM 会有什么改变? 活跃了将近三年的 JSR 133,近期发布了关于如何修复 Java 内存模型(Java Memory Model, JMM)的公开建议

Java内存模型(JMM)

1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per Second,TPS)这个指标比较能说明问题,它代表着一秒内服务器平均能响应的请求数,而TPS值与程序的并发能力有着非常密切的关系.在讨论Java内存模型和线程之前,先简单介绍一下硬件的效率与一致性. 2.硬件的效率与一致性 由于计算机的存储设备与处理器的运算能力之间有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理