在堆上分配的对象

Posted

技术标签:

【中文标题】在堆上分配的对象【英文标题】:Objects allocated on heap 【发布时间】:2010-12-10 09:20:18 【问题描述】:

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

这两个字段的具体用途是什么。有人能解释一下吗?

【问题讨论】:

鉴于所有对象都是特定类型,但是运行时是否应该知道,除非它在某处记录类型...?不要担心阅读那种东西,担心你自己的代码。 @mP 没错——那么它为什么不记录值类型的信息呢?了解您的工具的工作原理总是值得的。 【参考方案1】:

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

方法查找(vtable) 检查演员表 如果您调用GetType,则查找Type 对象。

syncblock 字段主要用于锁定。它只在需要时才被填充,并且当一个锁始终没有争议时,CLR 会使用不需要任何外部数据的“瘦”锁。否则,它是进程范围表中的一个条目——我不知道表中内容的详细信息,但我想它就像在对象监视器上等待的线程列表。当然,最重要的信息是当前是否持有锁、由哪个线程持有以及它的计数是多少(由于 .NET 锁的可重入性)。

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

【讨论】:

不知道 GetHashCode 和同步块...您有更多相关信息吗?我找到了这个blogs.msdn.com/brada/archive/2003/09/30/50396.aspx,但它似乎只是 .NET 1.0/1.1... @thecoop:我没有其他任何关于手的参考,尽管我希望通过 C# 在 CLR 中提到它。 我相信同步块也用于存储 COM 互操作元数据和 AppDomainID(正如@JonSkeet 所说,它是“进程范围表中的一个条目。”) 【参考方案2】:

类型对象是 obj.GetType 调用返回的对象

用于同步的同步块

见:

CLR Memory Model Part 1 CLR Memory Model Part 2 More on locks

【讨论】:

【参考方案3】:

Monitor 类在后台使用同步块索引,因此也使用 lock 语句。

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于在堆上分配的对象的主要内容,如果未能解决你的问题,请参考以下文章

Java中对象都是分配在堆上吗?你错了!

NSDate - 默认初始化程序如何在堆上分配空间?

我应该啥时候在堆上分配? (C++)

Unix系统编程()在堆上分配内存

java创建对象时分配内存方式,是堆上分配还是栈上分配?

使用 malloc 在堆上分配内存的幕后花絮