在.NET中,为什么lock(someObject)
实现它的方式?我看到它的方式,有两个选项来存储同步信息:
memory address -> synchronization info
synchronization info
。在第一个实现中,没有锁定的对象没有内存开销 - 它们没有获得任何哈希表条目。但是,.NET使用第二种实现,在每个.NET对象的标头中存储同步块索引字段 - 甚至是那些从未锁定的对象。
这种选择背后的动机是什么?这针对哪些方案进行了优化?
答案 0 :(得分:3)
CLR有一个标题字用于同步信息和其他东西,例如对象标识哈希码。 It's a multi-purpose field.
但是,你的论证仍然有效:这可以使用全局哈希表来实现。这将减少大多数对象的内存和对象创建成本,并增加锁定和标识哈希代码成本。我可以看到这有意义,但它依赖于工作量。
此外,从链接文章看起来COM和MarshalByRefObject信息也存储在那里。由于性能原因,这可能会强制将此数据包含在对象标头中。例如,MarshalByRefObject
上的每个方法调用都有一些开销来检查远程对象。也许有实际知识的人可以评论/回答这个想法。
更主观地说,我认为能够锁定每个对象首先是糟糕的设计。可能,这仅用于Java兼容性。整个MarshalByRefObject
想法也是一个完整的设计失败。 (COM互操作可以。)
答案 1 :(得分:2)
除了在执行多线程编程时难以获得同步之外,另一个挑战是创建同步原语的性能开销。在.NET框架使用每个对象的同步信息块引入其监视器之前,锁定意味着创建和获取内核模式原语(临界区或互斥锁)。
每个对象的性能提升始终具有同步块,超过了额外的内存开销。所以它是速度与空间的权衡。