问题 Nullable 的大小是多少?


所以,实际上有两个问题:

  1. 一个 int (Int32)被指定为(显然)32位。怎么样? int? (Nullable<int>)?我的直觉告诉我,对于整数,它将是32位,加上布尔的8位,但实现可能比这更复杂。
  2. 我会回答我自己的问题 sizeof(int?);但作为 int? 是托管类型,这是不允许的。我知道类型的大小可能是依赖于平台的,而对于包含对其他对象的引用的对象,a sizeof类似的操作会产生误导。但是,在给定当前环境的情况下,是否有办法获得托管类型的“基线”大小(即,新实例化的实例的大小)?

2270
2017-08-24 18:40


起源

可能重复 Nullable <T>的内存占用量是多少 - Adam Sills


答案:


你可以看看 ildasm 或反射器。

如果有两个字段:a bool 和a T,所以可能是8个字节(假设4字节对齐)。


6
2017-08-24 18:45



很好,用这个学到了新东西!这完全有道理,但我没有考虑对齐问题(我猜这就是当你在游戏后期进入软件开发而没有CS教育时会发生什么)。 - Dan Tao


永远不要问这样的问题是非常重要的,因为你不会得到一个正确的答案。

但是,无论如何你做了:最小大小是0字节。当JIT优化器设法将值保存在CPU寄存器中时,您将获得该值。 bool的下一个大小是2个字节?和字节?,HasValue为1个字节,值为另一个字节。你很少得到它,因为局部变量必须与一个4的倍数对齐。额外的2个字节的填充根本就不会被使用。

下一个尺寸是3个简称?和char?,你现在得到1个字节的填充。

向下一个大跃进,int?需要5个字节,但填充增加到8个。

等等。你可以通过写一些这样的代码来找到它:

        int front = 42;
        bool? center = null;
        int back = 43;
        Console.WriteLine("", front, center, back);

并使用调试器查看机器代码指令。注意ebp寄存器偏移量。并注意堆栈增长。


6
2017-08-24 19:13





我找到了一个关于这个问题的治疗方法 这里,包括用于测试内存使用情况的简单控制台应用程序的代码。

基本上,

...这表明可以为空的类型   包装器需要4个字节的存储空间......


2
2017-08-24 18:55





考虑 Marshal.SizeOf 方法。它允许获取托管值类型的大小。这很奇怪,但看起来像可空类型的大小等于它们的类型参数的大小(int的大小?等于int的大小等)


0
2017-08-24 18:47



AFAIK你不能编组一个可以为空的值。因此,您收到的数据不正确。 - Daniel Rose
Microsoft文档说:“对象的非托管和托管大小可能不同。” - 所以这种方法不可靠。 - MarkusSchaber