如何检查引用需要多少字节?

时间:2013-07-04 19:57:22

标签: c# .net reference

来自第22页的C# 5.0 in a Nutshell: The Definitive Reference;

  

引用类型需要单独分配内存   参考和对象。该对象消耗与其字段一样多的字节,   加上额外的管理开销。精确的开销是   本质上是.NET运行时实现的私有,但是   至少开销是八个字节,用于存储密钥   对象的类型,以及其锁定状态等临时信息   用于多线程和用于指示是否已修复的标志   从垃圾收集器的运动。 每个对象的引用   需要额外的四个或八个字节,具体取决于.NET   运行时在32位或64位平台上运行。

我不太确定我完全理解这个大胆的部分。它说在32位平台上一个引用需要四个字节,在64位平台上它需要八个字节。

所以,我们说我们有

string s = "Soner";

如何查看此s引用所需的字节数?

3 个答案:

答案 0 :(得分:6)

您可以使用Environment.Is64BitProcess。如果是,则每个引用将为8个字节。如果不是,则每个引用将是4个字节。引用的类型以及它引用的对象的内容是无关紧要的。

编辑:正如现在删除的答案所述,IntPtr.Size更简单。

编辑:正如评论中所述,虽然当前 CLR中的所有引用都是相同的大小,但它可能会在某个时刻沿着类似的路径走向Hotspot,它使用“压缩” oops“在许多情况下即使在64位进程中也将引用存储为32位值(不限制可用内存)。

答案 1 :(得分:2)

如果确实希望计算引用的大小,那么使用此Reference.Size应该有效:

using System;
using System.Reflection.Emit;

public static class Reference
{
    public static readonly int Size = new Func<int>(delegate()
    {
        var method = new DynamicMethod(string.Empty, typeof(int), null);
        var gen = method.GetILGenerator();
        gen.Emit(OpCodes.Sizeof, typeof(object));
        gen.Emit(OpCodes.Conv_I4);
        gen.Emit(OpCodes.Ret);
        return ((Func<int>)method.CreateDelegate(typeof(Func<int>)))();
    })();
}

但是,与其他答案一起使用可能是一个更好的主意。

答案 2 :(得分:1)

要扩展Jon Skeet的答案,要获得可能的字节数,你应该这样做:

int bytesInRef = Environment.Is64BitProcess ? 8 : 4;

但是,这是实施细节。您不仅要担心这一点,还应该忽略这一点。这是关于(另一个)实施细节的好博客文章,但它仍然适用,因为它讨论了实施细节以及您不应该信任它们或依赖它们。这里:The Stack Is An Implementation Detail