论坛首页 Java企业应用论坛

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

浏览 9380 次
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-04-10  
看了楼上的一段话,想了很久,提出如下问题:
1,轻量级的锁 使用场景是 “没有多线程竞争”【原话:轻量级的锁是指在没有多线程竞争时,让虚拟机不去动用操作系统的互斥量】, 是为了 加重量级的锁做准备吧,这样理解ok不?
2, JVM (SunJDK1.6+) 是开启轻量级锁的。一个线程进入了一个对象,访问了该对象的成员变量,同时另外一个线程也需要访问该对象的 同一成员变量,这时轻量级锁膨胀为重量级锁。第二个线程 须等待第一个线程的释放该对象。 貌似这个过程全部由JVM完成,程序员不需要 为对象添加同步的代码【比如添加synchronized(this)】 。 是这样的吗?
0 请登录后投票
   发表时间:2011-04-10  
学习了。。。

原来GC的Mark是在对象头里。
对1.6轻量级锁的理解为用对象的MarkWord和线程的LockRecord来标识此对象正在被某个线程访问。如何标识的呢?存储Thread的ID什么的吗?另外这样做的意义有哪些呢?

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

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

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

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


噢?是这样啊? 我一直以为是完全使用非阻塞的CAS来取代锁.如果jvm会自动从CAS转向锁,那岂不是jvm会有个cas计数?CAS重试n次后转向锁? 另外,我一直理解的是,CAS是通过操作系统调用特殊的cpu指令实现的,而以前的锁恰恰只是jvm自己实现的...
貌似我一直完全理解错了...

以下是一些以前存的文章:

IBM-Java 理论与实践: 非阻塞算法简介
透过 Linux 内核看无锁编程


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

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

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

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


噢?是这样啊? 我一直以为是完全使用非阻塞的CAS来取代锁.如果jvm会自动从CAS转向锁,那岂不是jvm会有个cas计数?CAS重试n次后转向锁? 另外,我一直理解的是,CAS是通过操作系统调用特殊的cpu指令实现的,而以前的锁恰恰只是jvm自己实现的...
貌似我一直完全理解错了...

以下是一些以前存的文章:

IBM-Java 理论与实践: 非阻塞算法简介
透过 Linux 内核看无锁编程




这是从一本书里截取到都
引用
现在的处理器(包括 Intel 和 Sparc 处理器)使用的最通用的方法是实现名为“比较并交换(Compare And Swap)”或 CAS 的原语。(在 Intel 处理器中,比较并交换通过cmpxchg 系列指令实现。PowerPC 处理器有一对名为“加载并保留”和“条件存储”的指令,它们实现相同的目地;MIPS 与 PowerPC 处理器相似,除了第一个指令称为“加载链
接”。)

0 请登录后投票
   发表时间:2011-04-11  
IcyFenix 写道
Anddy 写道
这里讲到了轻量级锁,重量级锁 , 这个“锁” 应该 说的是 对象锁 。 比如一个对象 存在锁,其他线程必须等待 其 释放锁 后才能使用该对象 , 比如用synchronized(this){ ...} 给对象加锁 。

======
不明白的地方在于:这里的锁 有 轻量级 和重量级 区分 。  什么情况下对象锁是重量级的,什么情况对象锁是轻量级的 。


那把上面那个片段的前面也贴出来回答你这个问题。




这个我不太明白了。

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

所谓轻量级是不是说wait-free或Lock-free之类的东东。
0 请登录后投票
   发表时间:2011-04-11  
IcyFenix 写道
首先不要混淆了概念。
重量级的锁是指使用操作系统提供的互斥量保证共享数据在多线程竞争时被串行访问。
轻量级的锁是指在没有多线程竞争时,让虚拟机不去动用操作系统的互斥量,而改为使用对象的MarkWord和线程的LockRecord来标识共享数据正在被某个线程访问,这个标识操作是通过CAS来完成的。只要没有其他线程再进来,那轻量级锁就成功节省了一些性能开销。但如果有其他线程进来,那轻量级锁就要失效掉,膨胀回重量级锁来完成阻塞同步,这种场景下轻量级锁实际是比直接一开始就用重量级锁更加慢的(多了CAS的开销)。

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

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

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


上个回复中部分说明,所谓轻量级就是非阻塞同步Wait-free或Lock-free的操作,一般是mfence实现,和CPU架构有关。
0 请登录后投票
   发表时间:2011-04-11  
mercyblitz 写道

这个我不太明白了。

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

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


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

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

  • 大小: 6.8 KB
0 请登录后投票
   发表时间:2011-04-11  
IcyFenix 写道
mercyblitz 写道

这个我不太明白了。

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

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


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

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




哎,我是对他的说法不明白,不是对概念!我以为是什么新玩意!
0 请登录后投票
   发表时间:2011-04-11   最后修改:2011-04-11
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还有虚拟化版本,可以直接安装在裸机上,这种方式下虚拟机的行为操作系统是可知的,线程操作就无需状态切换的。
0 请登录后投票
   发表时间:2011-04-11  
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 请登录后投票
论坛首页 Java企业应用版

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