对象与 byte[0] 作为锁
我之前评论过这个问题(“为什么java.lang.Object不是抽象的?”)指出我听说使用 byte[0]
作为锁比使用 java.lang.Object
稍微更有效。我确信我在某处读过这篇文章,但我不记得在哪里:有谁知道这是否属实?
我怀疑这是由于 byte[0]
的实例化需要比 Object
稍少的字节代码,尽管有人指出 byte[0]
> 需要额外的存储空间才能存储长度字段,因此听起来这可能会抵消任何好处。
I commented earlier on this question ("Why java.lang.Object is not abstract?") stating that I'd heard that using a byte[0]
as a lock was slightly more efficient than using an java.lang.Object
. I'm sure I've read this somewhere but I can't recall where: Does anyone know if this is actually true?
I suspect it's due to the instantiation of byte[0]
requiring slightly less byte code than Object
, although it was pointed out that byte[0]
requires additional storage in order to store the length field and so it sounds like this might negate any benefit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 java.lang.instrument.Instrumentation 检查大小:
Object 使用 8 个字节,byte[0] 需要 16 个字节。 (不确定大小是否以字节为单位,未记录)。
我还花时间创建了一个 Object 和一个 byte[0] (2 次):Object 是赢家。
(所有测试均在 DELL 笔记本电脑、Intel 2GHz、Windos XP 上运行)
使用
客户端
VM使用
服务器
VM我将继续使用
new Object()
,不仅仅是因为可读性:-)Code
Timer* 使用
ThreadMXBean
来获取时间。* Timer 是我为计时而创建的类,它不是 Java 计时器之一。
Using java.lang.instrument.Instrumentation to check the sizes:
Object uses 8 bytes, byte[0] needs 16 bytes. (not sure if the size is in bytes, not documented).
I also got the time to create an Object and a byte[0] (2 times): Object is the winner.
(all tests run on a DELL laptop, Intel 2GHz, Windos XP)
Using the
client
VMUsing the
server
VMI will stay with
new Object()
, not only because of readability :-)The Code
Timer* uses
ThreadMXBean
to get the times.* Timer is a class I made for timming, it is not one of the Java Timer's.
我很好奇,想测试一下。源代码:
字节码:
所以你说得对,数组的字节码更短,因为数组创建有自己的 JVM 操作码。但这意味着什么?没什么,真的。它是虚拟机,因此绝对不能保证更少的字节码指令意味着实际物理 CPU 的工作量更少。当然,我们可以开始分析,但这毫无意义。如果确实存在差异,无论哪种方式,都永远不会重要。如今,对象创建速度快得令人难以置信。在测量总时间之前,您可能必须开始使用
long
作为循环索引。I got curious enough to test it. Sourcecode:
Bytecode:
So you're right in that the byte code is shorter for arrays, because array creation has its own JVM opcode. But what does that mean? Nothing, really. It's a virtual machine, so there's absolutely no guarantee that fewer bytecode instructions mean less work for the actual physical CPU. We could start profiling of course, but that would be quite pointless. If there is a difference at all, no matter which way, it will never ever matter. Object creation is incredibly fast nowadays. You'd probably have to start using
long
for your loop index before you can even measure the total time.根据
Java 语言规范, "所有类和数组类型继承了 Object 类的方法”,所以我不知道 byte[0] 如何能够变得更高效。
这对于 第一版来说似乎是正确的规范以及:“数组类型的超类被认为是对象”。
According to the
Java Language Spec, "all class and array types inherit the methods of class Object", so I don't know how byte[0] could manage to be more efficient.
That seems to be true for the first edition of the spec as well: "The superclass of an array type is considered to be Object".
恕我直言,使用数组更有可能让读者感到困惑。
创建较少的对象比创建更多的对象更有效,因此,如果它确实创建了足够多的重要对象,那么您就创建了太多对象。
Using an array is more likely to confuse the reader IMHO.
Creating less objects is more efficient than creating more, so if it ever did create enough objects that it mattered, you are creating too many.
Java中使用空数组作为锁对象的模式与性能关系不大。
空数组(甚至
new Object[0]
)更可取,因为它们是可序列化的。通过使用new Object()
,您将放弃自动序列化。我习惯了这样做(从不关心性能):
原始数组需要更少的字节码来创建,所以也许
new byte[0]
会“更好”。请参阅:可以为可序列化类设置瞬态锁吗?
The pattern of using an empty array in Java as a lock object has little to do with performance.
Empty arrays (even
new Object[0]
) are preferable because they are serializable. By usingnew Object()
you're giving up automatic serialization.I got used to doing (never caring about performance):
Primitive arrays take less bytecode to create, so maybe
new byte[0]
would be "better".See: Is it okay to to make the lock transient for a Serializable class?
你的问题提到了“效率”,但没有说你追求什么样的效率。到目前为止,答案涉及对象的大小,但是在任一表示中取消引用和使用内在锁的运行时成本应该是相同的。
您还可以比较使用内在锁与使用
java.util.concurrent.locks.ReentrantLock
显式地或您自己编写的AbstractQueuedSynchronizer
。您是否可以容忍对单独分配的对象的额外引用需要更详细的问题来评估,但考虑到您已经在考虑字节数组,您必须考虑使用与您的this
参考。Your question mentions "efficiency", but doesn't say what kind of efficiency you're after. The answers thus far concern the size of the objects, but the run-time costs of dereferencing and using the intrinsic lock in either representation should be the same.
You can also compare the overhead of using intrinsic locks to using
java.util.concurrent.locks.ReentrantLock
explicitly or one you write yourself atopAbstractQueuedSynchronizer
. Whether you can tolerate an additional reference to a separately-allocated object requires more detail on your problem to assess, but given that you're already consideringbyte
arrays, you must be considering using an intrinsic lock distinct from yourthis
reference.