.NET:为什么要在每个对象中存储同步块?

Ser*_*kin 6 .net performance multithreading mutex

在 .NET 中,为什么是这样lock(someObject)实现的?在我看来,有两个选项可以存储同步信息:

  1. 要映射的全局哈希表 memory address -> synchronization info
  2. synchronization info在每个可能被锁定的对象内部存储指针或索引。

在第一个实现中,未锁定的对象没有内存开销——它们不会获得任何哈希表条目。然而,.NET 使用第二种实现,在每个单独的 .NET 对象的头中存储一个同步块索引字段——即使是那些从未被锁定的对象。

这个选择背后的动机是什么?这是针对哪些场景进行优化的?

usr*_*usr 4

CLR 有一个头字用于同步信息和其他内容,例如对象标识哈希码。这是一个多用途领域。

但是,您的论点仍然有效:这可以使用全局哈希表来实现。这将降低大多数对象的内存和对象创建成本,并增加锁定和身份哈希码成本。我认为这是有道理的,但它取决于工作负载。

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

更主观地说,我认为能够锁定每个对象首先就是糟糕的设计。可能这只是为了 Java 兼容性而保留的。整个MarshalByRefObject想法也是彻底的设计失败。(COM 互操作正常。)