【问题标题】:How reference type works internally? [closed]引用类型如何在内部工作? [关闭]
【发布时间】:2014-01-01 10:02:04
【问题描述】:
public class ReferenceType
{
   public int FName { get; set; }        
   public int LName { get; set; }        
}  

ReferenceType rt1;          //Line 6
rt1 = new ReferenceType();   //Line 7 >>have just split a single line statement<<

众所周知

引用类型是如何工作的,在上面的代码场景中

  • rt1 在堆栈中分配一部分内存,以在将来保存some 对象的引用(第 6 行)

  • rt1 被分配了在堆上创建的对象的引用 [a specific]

现在,这个引用在内部是什么样子的,rt1 是否保存(创建的)对象的地址,十六进制,就像 c++ 中的指针一样,还是其他什么?

【问题讨论】:

标签: c#


【解决方案1】:

你的第一个点不正确。

在堆栈上添加了一个引用。然后这个引用引用堆上的内存。

(免责声明:以下声明是我认为它的工作原理。在 SSCLI 中肯定是这种方式)

引用被实现为指针。但没有正式的要求说明它们必须是指针。这可能会随时由 Microsoft 自行决定更改。它们(当前)指向对象的方法表。

一个对象看起来像这样:

       +-------------+
       |             |
       |  Reference  |
       |             |
       +------+------+
              |
              |                +-------------------------------+
              |                |          Object header        |
              +--------------->|-------------------------------|
                               |                               |
                               |                               |
                               |                               |
                               |           Method table        |
                               |                               |
                               |                               |
                               |                               |
                               |                               |
                               +-------------------------------+

标头包含一个同步块索引和一个指向对象类型定义的指针。重要的是要知道,引用知道它们指向什么......指针不必知道这一点。这是由 CLR 强制执行的。

是的,这是一个您不必关心的实现细节。但我认为了解它没有任何问题。

只要您不依赖实施细节。了解它们不会杀死您。

【讨论】:

  • +1...是的,刚刚记得那个(堆栈)点...。
  • 方法表?我不能发誓(它可能会改变),但它不应该指向这一点。它应该(必须?)指向一个 handles 表(在那里,引用另一个指针,您将拥有方法表)。就像你说的,这甚至不是 C++ 指针的实现方式(至少在我知道的编译器中)
  • @Adriano 它确实指向 SSCLI 中的方法表(没有访问 Microsoft 的 CLR,我们无法确定它们的实现)。但是,您可能想到的额外跳数是用于 JIT 编译之前的方法 thunks .. ?
  • @downvoter 如果您认为某些内容不正确,我很乐意修改此内容。就像我说的……这是完全基于共享源 CLI 的……所以我不知道微软 CLR 的内部工作原理。
  • 我只是假设但是:指向引用的固定指针将访问其字段,然后它将指向除方法表之外的其他内容。如果转储,它与引用本身的值不同。最后,“调用”不需要引用方法表(当 JITed 时),但“callvirt”需要。双重尊重(对象本身和虚拟方法)是它变慢的原因之一。那么对象引用不应该直接指向方法,而是指向字段(它们不必一起成长)。我再次假设......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 2017-03-26
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多