2011-12-29 29 views
6

在着名的实践中的Java Concurrency第2.4节中,它指出内部锁定方法与显式锁定不同是一个糟糕的设计决策,因为它的混淆和“......它迫使JVM实现者在对象大小和锁定之间进行权衡性能。” 有人可以解释如何对象大小影响锁定性能?Java中的对象大小和锁定性能之间是否存在关系?

+1

与'synchronized'类型的锁应该没有关系(从我的实现经验来看),并且从简要回顾Java 5锁定方案,我不会直接看到那里可能存在依赖关系。当然,它实际上需要更多的存储空间来实现单独的'Lock'对象,但这应该是一个固定的开销。 – 2011-12-29 16:02:47

+0

@HotLicks多数民众赞成在我感到惊讶,大小shudnt有任何额外的开销,谢谢! – meer 2011-12-30 11:22:57

回答

5

那么因为每个对象都可以锁定,这意味着每个对象都必须有足够的位置来存储锁定时需要的所有信息。

这是相当没有吸引力的,因为绝大多数的物体永远不会被锁定,所以我们浪费了大量的空间。所以在实践中,Hotspot通过使用2位来记录对象的状态并根据这两位重用对象头的其余部分来解决这个问题。

然后是整个偏向/无偏向锁定的东西..好吧,你可以开始阅读关于它here。热点文档不是我所谓的扩展,但锁定和对象头文件比其他大多数代码更好。但有疑问:阅读源代码。

PS:我们也有类似的问题,也是每个对象的本地哈希码。如果你的GC洗牌的话,“只用内存地址”就不太好。 (但是与锁定相反,如果我们需要此功能,则没有真正的选择)

+0

感谢您的信息,基本上它是关于所有原始同步,而不管用于锁定的特定对象的大小 – meer 2011-12-30 11:23:59

+0

您是否有一些具体细节去处理这些语句? “很多”的空间?锁定时需要什么信息? – Toby 2012-01-05 08:09:05

+0

@Toby至少是TID和递归计数器。有关详细信息,您需要查看热点源中的重锁类。考虑到这被添加到每个对象,即使1-2个字也是“很多空间”。 – Voo 2012-01-05 20:43:23

2

最有效的锁使用原生字大小,例如32位字段。但是,您不希望将4个字节添加到每个对象,而是使用AFAIK 1位,但设置此位比设置字大小更昂贵。

+0

即使我们使用字大小的字段,嗯,我们可以做到没有CAS吗?如果不是,它基本上只读+位混洗+ CAS与CAS - 可能并不坏,但仍然较慢。 – Voo 2011-12-29 16:22:28

+0

@Voo在我的经验中并不那么糟糕,因为'synchronized'可以通过JIT进行优化,方法是Lock不是。 – 2011-12-29 16:35:15

+0

我在谈论同步实现。即使我们使用了一个字面化的锁头,我们仍然需要一个CAS来控制位混洗,所以在那里没有太大的区别。尽管我们可能正在谈论对方。 – Voo 2011-12-29 16:49:30

相关问题