.NET:为什么在每个对象中存储Sync Block?

时间:2016-10-31 16:59:50

标签: .net multithreading performance mutex

在.NET中,为什么lock(someObject)实现它的方式?我看到它的方式,有两个选项来存储同步信息:

  1. 要映射memory address -> synchronization info
  2. 的全局哈希表
  3. 将指针或索引存储到可能被锁定的每个对象内的synchronization info
  4. 在第一个实现中,没有锁定的对象没有内存开销 - 它们没有获得任何哈希表条目。但是,.NET使用第二种实现,在每个.NET对象的标头中存储同步块索引字段 - 甚至是那些从未锁定的对象。

    这种选择背后的动机是什么?这针对哪些方案进行了优化?

2 个答案:

答案 0 :(得分:3)

CLR有一个标题字用于同步信息和其他东西,例如对象标识哈希码。 It's a multi-purpose field.

但是,你的论证仍然有效:这可以使用全局哈希表来实现。这将减少大多数对象的内存和对象创建成本,并增加锁定和标识哈希代码成本。我可以看到这有意义,但它依赖于工作量。

此外,从链接文章看起来COM和MarshalByRefObject信息也存储在那里。由于性能原因,这可能会强制将此数据包含在对象标头中。例如,MarshalByRefObject上的每个方法调用都有一些开销来检查远程对象。也许有实际知识的人可以评论/回答这个想法。

更主观地说,我认为能够锁定每个对象首先是糟糕的设计。可能,这仅用于Java兼容性。整个MarshalByRefObject想法也是一个完整的设计失败。 (COM互操作可以。)

答案 1 :(得分:2)

除了在执行多线程编程时难以获得同步之外,另一个挑战是创建同步原语的性能开销。在.NET框架使用每个对象的同步信息块引入其监视器之前,锁定意味着创建和获取内核模式原语(临界区或互斥锁)。

每个对象的性能提升始终具有同步块,超过了额外的内存开销。所以它是速度与空间的权衡。

相关问题