打捞回帖、回信来发博客是个偷懒的好办法 :wink: ZZZzzz....ZZZzzz....
------------------------------------------------------------
[quote="xuhang1128"]1.比如上面线程1执行to方法,我觉得就是先将3赋值给a,然后a写到主内存,
上面 assign操作所说的, transfers a value from the thread's execution engine into the thread's working copy of a variable
这句话里面的 thread's execution engine和 thread's working copy of a variable分别代表什么啊,我的理解就是将3赋值给a,然后又是用store命令将 thread's working copy of a variable搞到 main memory,这时候还不完了吗,为什么后面又是 write?
2.还有上面的线程2执行的fro方法的read所说的master copy of a variable to a thread's working memory ,这里的
master copy of a variable 又是指什么呢?规范里面好像说 thread's working memory可以使寄存器,高速缓存之类的东西,之后又用load操作将main memory 将value值搞到 thread's working copy of a variable,这里的 thread's working copy of a variable是局部变量吗还是什么 [/quote]
讨论前,先来看看这几个操作的含义(书上有我就不重新打一遍了,但与出版社有版权协议,不太方便粘贴复制,就给你贴图片了):
[img]http://dl.iteye.com/upload/attachment/493768/94cf021c-a05e-35c6-824d-e84f656df7a8.png[/img]
主内存和工作内存是什么,在这段前面的2节里面有更详细的介绍,内容太多我就不全部粘贴了,反正还有2周书就应该能出来。我做个类比可能好理解一些,简单来说你可以把它们的关系理解成PC机里面的“内存”和“处理器Cache”之间的关系,所有数据在内存中都用,但是要用的时候Cache中都有一份拷贝,如果是多CPU或者多核处理器,同一份数据还可能在不同的Cache中还有拷贝,解决内存与Cache的一致性问题,硬件里有各种一致性协议。而JVM的内存模型其中一个任务也是解决main memory和working memory之间的一致性问题。
“thread's working copy of a variable”不是局部变量,它就是工作内存中的变量拷贝副本而已,事实上在JMM中一开始就从定义了“variable”的含义,它包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为后者是线程私有的 ,不会被共享,自然就不存在竞争问题。
关于为何store之后又要write的问题,从上面图片你可以看到,这2个操作是作用在不同区域上的,你把main memory和work memory看作2间房子,这2个操作就好比开门,要把物品A从房间以拿到(复制到)房间B,自然要分别进行“拿出来”和“放进去”2个操作。为什么不定义一个诸如transfer之内的操作一次过完成呢?那是因为这6个操作都是“原子的”,不可拆分,如果定义一个原子的“transfer”操作当然也可以完成任务,但原子操作的范围更大,也就意味这个操作的锁定时间更长。这与JMM规范的基本思想:既准确又宽松(见下面图片)相违背了。
[img]http://dl.iteye.com/upload/attachment/493773/4103bb80-6361-324d-87e3-d69b9bb861c5.png[/img]
[quote="xuhang1128"]JVM栈,操作数栈,本地栈只是抽象的概念,HotSpot VM使用的Java栈就直接融合了概念上的JVM栈与本地栈,而在被编译过的方法的栈帧里不存在操作数栈——消失了 。不要把抽象概念与具体实现混为一谈。
这是别人说的,请问上面说的编译过的方法操作数栈消失了是什么意思啊[/quote]
首先,需要弄清楚概念,你这里发生混淆了。HotSpot里面的“本地方法栈”(Native Method Stacks)和“Java虚拟机栈”(Java Virtual Machine Stacks)合二为一了。这意味着Java方法调用和本地方法(譬如JNI方法调用)使用的是同一个栈,从使用上理解,就是-Xoss参数和-Xss参数变成了同一个,因此在HotSpot里面-Xoss无效。而“操作数栈”(Operand Stack)是栈帧(Stack Frame)的一部分,栈帧说白了就是Java虚拟机栈的栈元素。它是客观存在的,不会消失。由于JVM规范的指引或者说是限制,各种Java虚拟机都是基于栈结构的,这里的栈就是操作数栈,它是指令执行的基本前提。所以在各种虚拟机中,甚至在一个虚拟机的解析和编译执行引擎中它可以有不同的存在形式,但是总谈不上“消失”的([color=red]这里有陷阱,请看撒迦的回帖[/color])。当然,不基于栈的虚拟机,譬如Google Android的Dalvik虚拟机(基于寄存器架构)就可以没有操作数栈,当然,那也已经不是严格意义上的“JVM”了。
[quote="xuhang1128"]字节码指令不还有对操作数栈的操作码,不懂了哎[/quote]
“操作数栈的操作码”这个提法不妥当的。字节码指令,或者说操作码(Opcodes)不放在操作数栈上,操作数栈既然都命名为“操作数(Operand)”,那肯定是只放运算参数、中间过程结果和运算结果的啊,放个Opcodes上去有什么意思呢?
------------------------------------------------------------
[quote="xuhang1128"]1.比如上面线程1执行to方法,我觉得就是先将3赋值给a,然后a写到主内存,
上面 assign操作所说的, transfers a value from the thread's execution engine into the thread's working copy of a variable
这句话里面的 thread's execution engine和 thread's working copy of a variable分别代表什么啊,我的理解就是将3赋值给a,然后又是用store命令将 thread's working copy of a variable搞到 main memory,这时候还不完了吗,为什么后面又是 write?
2.还有上面的线程2执行的fro方法的read所说的master copy of a variable to a thread's working memory ,这里的
master copy of a variable 又是指什么呢?规范里面好像说 thread's working memory可以使寄存器,高速缓存之类的东西,之后又用load操作将main memory 将value值搞到 thread's working copy of a variable,这里的 thread's working copy of a variable是局部变量吗还是什么 [/quote]
讨论前,先来看看这几个操作的含义(书上有我就不重新打一遍了,但与出版社有版权协议,不太方便粘贴复制,就给你贴图片了):
[img]http://dl.iteye.com/upload/attachment/493768/94cf021c-a05e-35c6-824d-e84f656df7a8.png[/img]
主内存和工作内存是什么,在这段前面的2节里面有更详细的介绍,内容太多我就不全部粘贴了,反正还有2周书就应该能出来。我做个类比可能好理解一些,简单来说你可以把它们的关系理解成PC机里面的“内存”和“处理器Cache”之间的关系,所有数据在内存中都用,但是要用的时候Cache中都有一份拷贝,如果是多CPU或者多核处理器,同一份数据还可能在不同的Cache中还有拷贝,解决内存与Cache的一致性问题,硬件里有各种一致性协议。而JVM的内存模型其中一个任务也是解决main memory和working memory之间的一致性问题。
“thread's working copy of a variable”不是局部变量,它就是工作内存中的变量拷贝副本而已,事实上在JMM中一开始就从定义了“variable”的含义,它包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为后者是线程私有的 ,不会被共享,自然就不存在竞争问题。
关于为何store之后又要write的问题,从上面图片你可以看到,这2个操作是作用在不同区域上的,你把main memory和work memory看作2间房子,这2个操作就好比开门,要把物品A从房间以拿到(复制到)房间B,自然要分别进行“拿出来”和“放进去”2个操作。为什么不定义一个诸如transfer之内的操作一次过完成呢?那是因为这6个操作都是“原子的”,不可拆分,如果定义一个原子的“transfer”操作当然也可以完成任务,但原子操作的范围更大,也就意味这个操作的锁定时间更长。这与JMM规范的基本思想:既准确又宽松(见下面图片)相违背了。
[img]http://dl.iteye.com/upload/attachment/493773/4103bb80-6361-324d-87e3-d69b9bb861c5.png[/img]
[quote="xuhang1128"]JVM栈,操作数栈,本地栈只是抽象的概念,HotSpot VM使用的Java栈就直接融合了概念上的JVM栈与本地栈,而在被编译过的方法的栈帧里不存在操作数栈——消失了 。不要把抽象概念与具体实现混为一谈。
这是别人说的,请问上面说的编译过的方法操作数栈消失了是什么意思啊[/quote]
首先,需要弄清楚概念,你这里发生混淆了。HotSpot里面的“本地方法栈”(Native Method Stacks)和“Java虚拟机栈”(Java Virtual Machine Stacks)合二为一了。这意味着Java方法调用和本地方法(譬如JNI方法调用)使用的是同一个栈,从使用上理解,就是-Xoss参数和-Xss参数变成了同一个,因此在HotSpot里面-Xoss无效。而“操作数栈”(Operand Stack)是栈帧(Stack Frame)的一部分,栈帧说白了就是Java虚拟机栈的栈元素。它是客观存在的,不会消失。由于JVM规范的指引或者说是限制,各种Java虚拟机都是基于栈结构的,这里的栈就是操作数栈,它是指令执行的基本前提。所以在各种虚拟机中,甚至在一个虚拟机的解析和编译执行引擎中它可以有不同的存在形式,但是总谈不上“消失”的([color=red]这里有陷阱,请看撒迦的回帖[/color])。当然,不基于栈的虚拟机,譬如Google Android的Dalvik虚拟机(基于寄存器架构)就可以没有操作数栈,当然,那也已经不是严格意义上的“JVM”了。
[quote="xuhang1128"]字节码指令不还有对操作数栈的操作码,不懂了哎[/quote]
“操作数栈的操作码”这个提法不妥当的。字节码指令,或者说操作码(Opcodes)不放在操作数栈上,操作数栈既然都命名为“操作数(Operand)”,那肯定是只放运算参数、中间过程结果和运算结果的啊,放个Opcodes上去有什么意思呢?