我很想知道 C# 对象引用在运行时(在 .NET CLR 中)如何在内存中表示。我想到的一些问题是:
对象引用占用多少内存?在类的范围和方法的范围中定义时有什么不同吗?它所在的位置是否根据此范围(堆栈与堆)而有所不同?
对象引用中维护的实际数据是什么?它只是一个指向它所引用的对象的内存地址还是还有更多内容?这是否因它是在类还是方法的范围内定义而有所不同?
与上面的问题相同,但这次是在讨论对引用的引用时,就像将对象引用通过引用传递给方法时一样。 1 和 2 的答案有何变化?
.NET 堆和堆栈 http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx这是对堆栈和堆如何工作的彻底处理。
C# 和许多其他使用堆的 OOP 语言的一般参考用途句柄而不是指针在此上下文中进行参考(C# 也能够使用指针!)指针类比适用于一些一般概念,但此概念模型对于此类问题不适用。请参阅 Eric Lippert 关于此主题的精彩帖子句柄不是地址 http://blogs.msdn.com/b/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx
说句柄是指针的大小是不合适的。(尽管可能巧合是相同的)句柄是对象的别名,并不要求它们是对象的正式地址。
在这种情况下,CLR 恰好使用句柄的真实地址:来自上面的链接:
...CLR 实际上确实将托管对象引用实现为
垃圾收集器拥有的对象的地址,但这是一个
实施细节。
所以,是的,句柄在 32 位架构上可能是 4 个字节,在 64 字节架构上可能是 8 个字节,但这不是“肯定的”,而是不是直接因为指针。值得注意的是,具体取决于编译器的实现和某些类型的指针所使用的地址范围的大小可能不同.
有了所有这些上下文,您可能可以通过指针类比来对此进行建模,但重要的是要认识到句柄不一定是地址。如果 CLR 将来愿意的话,它可以选择更改此设置,并且 CLR 的消费者不应该知道更多。
这个微妙点的最终驱动力:
这是一个 C# 指针:
int* myVariable;
这是一个 C# 句柄:
object myVariable;
他们不一样。
您可以对指针执行诸如数学运算之类的操作,而这些操作不应使用句柄执行。如果您的句柄碰巧像指针一样实现,并且您像指针一样使用它,那么您在某些方面滥用了句柄,这可能会给您带来以后的麻烦。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)