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

本文关键字:多少 字节 引用 何检查 检查 | 更新日期: 2023-09-27 18:21:09

来自第22页中的C#5.0:最终参考;

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

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

所以,假设我们有

string s = "Soner";

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

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

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

编辑:正如在一个现已删除的答案中所指出的,IntPtr.Size甚至更简单。

编辑:正如评论中所指出的,尽管当前CLR中的所有引用都是相同的大小,但在某个时候,它可能会走上类似于Hotspot的路径,Hotspot在许多情况下使用"压缩oop"将引用存储为32位值,即使在64位进程中也是如此(不限制可用内存)。

如果真的计算引用的大小,使用这个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>)))();
    })();
}

但采用其他答案可能是一个更好的主意。

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

int bytesInRef = Environment.Is64BitProcess ? 8 : 4;

但是,这是一个实现细节你不仅不应该担心这一点,还应该忽略这一点。这里有一篇关于(另一个)实现细节的好博客文章,但它仍然适用,因为它谈到了实现细节,以及你不应该信任或依赖它们。这里:堆栈是一个实现细节