论坛首页 Java企业应用论坛

关于Java运行时数据区的内存分配问题(求解惑)

浏览 9379 次
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-04-11  
IcyFenix 写道
JE帐号 写道

另外,我一直理解的是,CAS是通过操作系统调用特殊的cpu指令实现的,而以前的锁恰恰只是jvm自己实现的...

嗯,我觉得这句话刚好说反了。

CAS并不是操作系统提供的,它直接依赖于硬件的指令集,如IA64、x86指令集中有cmpxchg指令完成CAS功能,在sparc-TSO也有casa指令实现,而在ARM和PowerPC架构下,则需要使用一对ldrex/strex指令来完成LL/SC的功能。

线程和线程的相关操作(创建、阻塞、唤醒),都不是JVM自己实现的(嗯,准确地说,现在的高性能虚拟机中不是自己实现的,在远古时代(JDK1.0),Java中的线程是称为“GreenThreads”的用户线程实现,这时候可以说是JVM自己实现),而是建立在操作系统的内核线程(或者说是内核线程的外部形态:轻量级进程(LWP),不区分那么清楚也可以)实现的,所以很多线程操作经常需要用户态内核态转换,所以才千方百计地希望有措施能代替操作系统提供的重量级锁。

当然,上面说的是通常意义的高性能虚拟机,如果要撞一下牛角尖,那JRockit还有虚拟化版本,可以直接安装在裸机上,这种方式下虚拟机的行为操作系统是可知的,线程操作就无需状态切换的。



严格来说,他没有说错!是操作系统调用CPU上面的指令,比如mfence,不同的CPU提供了汇编扩展。至于现代JVM,存在着Java线程和内核线程的M:N映射关系。老JVM线程实现,我认为主要还是当时Linux等操作系统没有线程的概念,更没有POSIX Thread API的提供。内核级别,进程和线程没有区别。
0 请登录后投票
   发表时间:2011-04-11  
轻量级锁不是锁,前面我已经说过了。它叫这个名字,你只能找官方算账了= =#,我是没啥好说滴。

性能当然不一定比锁更好,它能提高性能的依据仅仅是“对于大部分的锁,在整个同步周期内都是不存在竞争的”这一个经验数据罢了,这点在前面我也已经说过了。

lightweight-lock和非阻塞同步还是有不少区别的,虽然它也是用CAS,但它发挥作用的时候,实际上还没到“同步”上去,如果真要到了“同步”上,它就无法发挥作用,需要失效掉了。
0 请登录后投票
   发表时间:2011-04-11  
mercyblitz 写道
严格来说,他没有说错!是操作系统调用CPU上面的指令

“操作系统调用CPU上面的指令”这算操作系统的指令还是算CPU的指令这我觉得没有争论的意义,这个就到此为止吧。

mercyblitz 写道
至于现代JVM,存在着Java线程和内核线程的M:N映射关系。老JVM线程实现,我认为主要还是当时Linux等操作系统没有线程的概念,更没有POSIX Thread API的提供。内核级别,进程和线程没有区别。

这还是有点小瑕疵,M:N模型能不能支持,取决于操作系统,而不取决于JVM。至于远古时代的VM为使用用户线程是基于何种考虑,这点我就不好去猜测了。
0 请登录后投票
   发表时间:2011-04-11  
Anddy 写道
看了楼上的一段话,想了很久,提出如下问题:
1,轻量级的锁 使用场景是 “没有多线程竞争”【原话:轻量级的锁是指在没有多线程竞争时,让虚拟机不去动用操作系统的互斥量】, 是为了 加重量级的锁做准备吧,这样理解ok不?
2, JVM (SunJDK1.6+) 是开启轻量级锁的。一个线程进入了一个对象,访问了该对象的成员变量,同时另外一个线程也需要访问该对象的 同一成员变量,这时轻量级锁膨胀为重量级锁。第二个线程 须等待第一个线程的释放该对象。 貌似这个过程全部由JVM完成,程序员不需要 为对象添加同步的代码【比如添加synchronized(this)】 。 是这样的吗?



轻量级锁即非阻塞同步,是通过线程读取Java Heap中数据(数据可能被其他线程修改)和主存中比较,一般把比较和更新做一个原子操作,其他线程调用相同的代码,做类似的操作,数据一致性不一定100%的保证。而synchronized和Lock实现,均是通过调用OS的Thread API来实现的。JVM是不会自动选择的,而是通过代码解释执行相应的操作的。比如CAS,是调用Unsafe接口,对应unsafe CPP实现。
0 请登录后投票
   发表时间:2011-04-11  
IcyFenix 写道
mercyblitz 写道
严格来说,他没有说错!是操作系统调用CPU上面的指令

“操作系统调用CPU上面的指令”这算操作系统的指令还是算CPU的指令这我觉得没有争论的意义,这个就到此为止吧。

mercyblitz 写道
至于现代JVM,存在着Java线程和内核线程的M:N映射关系。老JVM线程实现,我认为主要还是当时Linux等操作系统没有线程的概念,更没有POSIX Thread API的提供。内核级别,进程和线程没有区别。

这还是有点小瑕疵,M:N模型能不能支持,取决于操作系统,而不取决于JVM。至于远古时代的VM为使用用户线程是基于何种考虑,这点我就不好去猜测了。



是的,M:N的话,目前好像之后Solaris支持,其他的貌似不支持。Linux下面就是Posix Thread API,这是1:1,呵呵。
0 请登录后投票
   发表时间:2011-04-11  
IcyFenix 写道
轻量级锁不是锁,前面我已经说过了。它叫这个名字,你只能找官方算账了= =#,我是没啥好说滴。

性能当然不一定比锁更好,它能提高性能的依据仅仅是“对于大部分的锁,在整个同步周期内都是不存在竞争的”这一个经验数据罢了,这点在前面我也已经说过了。

lightweight-lock和非阻塞同步还是有不少区别的,虽然它也是用CAS,但它发挥作用的时候,实际上还没到“同步”上去,如果真要到了“同步”上,它就无法发挥作用,需要失效掉了。



嗯,这个话题开启到“高级VM讨论组”里面,昨天我看了帖子,好久没有回复了,呵呵!
0 请登录后投票
   发表时间:2011-04-11  
IcyFenix 写道
首先不要混淆了概念。
重量级的锁是指使用操作系统提供的互斥量保证共享数据在多线程竞争时被串行访问。
轻量级的锁是指在没有多线程竞争时,让虚拟机不去动用操作系统的互斥量,而改为使用对象的MarkWord和线程的LockRecord来标识共享数据正在被某个线程访问,这个标识操作是通过CAS来完成的。只要没有其他线程再进来,那轻量级锁就成功节省了一些性能开销。但如果有其他线程进来,那轻量级锁就要失效掉,膨胀回重量级锁来完成阻塞同步,这种场景下轻量级锁实际是比直接一开始就用重量级锁更加慢的(多了CAS的开销)。

因此重量级锁还是轻量级锁,与采用synchronized还是j.u.c的lock没有什么联系,至少是完全不构成因果关系的。

而lightweight lock从“使用”的角度讲,程序员基本不需要选择(没法选择),也不需要太过关心,那些都是JVM的活。简单地说,基于互斥量的重量锁实际是一种悲观的并发策略,无论是否有竞争都先去加锁。而基于CAS的轻量锁则是一种乐观的并发策略,它先假设不会出现竞争,当真正出现竞争时再采取补救措施(膨胀)。因此在总是有竞争的场景下,重量级锁更快,在大多数情况都不出现竞争的场景下,轻量级锁会快一些;一般应用都是后者多于前者的,所以JVM(SunJDK1.6+)默认开着轻量级锁。

这样的解释能解答楼上的疑问了吗?


前几天也在看某篇博文,硬是看不清除里面对轻量级锁的解释

看了IcyFenix的解答,一目了然,太感谢了
0 请登录后投票
   发表时间:2011-04-11  
mercyblitz 写道
mercyblitz 写道
IcyFenix 写道
mercyblitz 写道

这个我不太明白了。

JDK在内部实现synchronized和Lock都是一个机制,只不过JVM参数可以调整锁机制,比如Spinning Lock,Ticket Lock和Biased Lock。

所谓轻量级是不是说wait-free或Lock-free之类的东东。


首先要明确,轻量级锁并不是真正意义上的“锁”,只是一种尽可能避免锁出现的优化措施。wait-free、lock-free是在算法实现层面的事情,这两者并不是同一件事情。

关于轻量级锁的原理,这个帖子的豆腐块上就有一篇介绍呀。




哎,我是对他的说法不明白,不是对概念!我以为是什么新玩意!


轻量级锁说法有点出入,压根不是锁,而是前面我的帖子回复中提到“非阻塞同步”。

再说“非阻塞同步”不一定比锁机制性能要好!
请参考:
http://blogs.sun.com/dave/entry/biased_locking_in_hotspot


说的直白些就是:
在轻度争用情况下采用“非阻塞同步”方式,效率更高.
在高度争用情况下,"锁机制"更好.
所以,需要根据预期命中率来评估使用哪种方式喽?


0 请登录后投票
   发表时间:2011-04-11  
JE帐号 写道
mercyblitz 写道
mercyblitz 写道
IcyFenix 写道
mercyblitz 写道

这个我不太明白了。

JDK在内部实现synchronized和Lock都是一个机制,只不过JVM参数可以调整锁机制,比如Spinning Lock,Ticket Lock和Biased Lock。

所谓轻量级是不是说wait-free或Lock-free之类的东东。


首先要明确,轻量级锁并不是真正意义上的“锁”,只是一种尽可能避免锁出现的优化措施。wait-free、lock-free是在算法实现层面的事情,这两者并不是同一件事情。

关于轻量级锁的原理,这个帖子的豆腐块上就有一篇介绍呀。




哎,我是对他的说法不明白,不是对概念!我以为是什么新玩意!


轻量级锁说法有点出入,压根不是锁,而是前面我的帖子回复中提到“非阻塞同步”。

再说“非阻塞同步”不一定比锁机制性能要好!
请参考:
http://blogs.sun.com/dave/entry/biased_locking_in_hotspot


说的直白些就是:
在轻度争用情况下采用“非阻塞同步”方式,效率更高.
在高度争用情况下,"锁机制"更好.
所以,需要根据预期命中率来评估使用哪种方式喽?




需要不同,“非阻塞同步”只保证了数据一致性,CAS原子同步,不能像锁那样做到乎互斥!
0 请登录后投票
   发表时间:2011-04-12   最后修改:2011-04-12
mercyblitz 写道

轻量级锁即非阻塞同步,是通过线程读取Java Heap中数据(数据可能被其他线程修改)和主存中比较,一般把比较和更新做一个原子操作,其他线程调用相同的代码,做类似的操作,数据一致性不一定100%的保证。而synchronized和Lock实现,均是通过调用OS的Thread API来实现的。JVM是不会自动选择的,而是通过代码解释执行相应的操作的。比如CAS,是调用Unsafe接口,对应unsafe CPP实现。


感觉 你的想法 跟IcyFenix 的想法不一样。

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics