2009-10-27 68 views
11

每当创建任何新对象时,都会在堆上创建该对象。为每个对象分配的内存有两个附加字段1)类型对象指针2)同步块索引。在堆上分配的对象

这两个字段的用法究竟是什么。任何人都可以阐明这一点吗?

+0

鉴于所有的对象都是特定的类型,除非它在某处记录类型,否则运行时应该知道的是?不要担心阅读那些东西,担心你自己的代码。 – 2009-10-27 07:30:06

+0

@mP确切地说 - 为什么它没有为价值类型记录这些信息?知道你的工具如何工作总是值得的。 – TarkaDaal 2012-11-27 09:21:55

回答

17

类型对象指针用于表示对象的类型。这是必需的:

  • 方法查找(虚函数表)
  • 检查蒙上
  • 寻找Type对象,如果你调用GetType

同步块字段主要用于锁定。它只在需要的时候才被填充,并且当锁总是无争议的时候,CLR使用不需要任何外部数据的“瘦”锁。否则,它是一个进程范围表中的条目 - 我不知道表中内容的细节,但我可以想象它是等待对象监视器的线程列表。当然,最重要的信息是锁是否被当前持有,通过哪个线程以及它的数量是多少(由于.NET锁的重入特性)。

如果您拨打GetHashCode()并且没有被覆盖,同步块也会被填入 - 基本上它使用进程范围表来分配一个稳定的数字。 (该对象的地址不够好,因为它可能会随时间而改变。)

+0

不知道关于GetHashCode和同步块......你有更多的信息吗?我发现这个http://blogs.msdn.com/brada/archive/2003/09/30/50396.aspx,但它似乎只是.NET 1.0/1.1 ... – thecoop 2009-10-27 13:38:20

+1

@thecoop:我没有任何其他参考手,虽然我希望它通过C#在CLR中提到。 – 2009-10-27 14:10:40

+0

我相信同步块也用于存储COM互操作元数据和AppDomainID(就像@JonSkeet所说的,它是“_process-wide_表”中的一个条目)。 – Sindhudweep 2013-05-17 17:57:51

2

同步块索引在Monitor类的引擎下使用,因此lock语句也是如此。

1

同步块索引的某些位也被GC用来将对象标记为垃圾,以防它不再被引用。