.net 什么是Nullable的内存占用< T>

s2j5cfk0  于 2023-05-19  发布在  .NET
关注(0)|答案(9)|浏览(227)

intInt32)的内存占用量为4字节。什么是内存占用:

int? i = null;

以及:

int? i = 3;

这是一般的还是类型相关的?

cbeh67ev

cbeh67ev1#

我不是100%确定,但我相信它应该是8个字节,4个字节用于int 32,(因为在32位机器上每个东西都必须是4字节对齐的)另外4个字节用于指示是否指定了整数值的布尔值。
注意,感谢@sensorSmith,我现在意识到.Net的新版本允许将可空值存储在较小的占用空间中(当硬件内存设计允许独立分配较小的内存块时)。在64位机器上,它仍然是8字节(64位),因为这是可以寻址的最小内存块。
例如,一个nullable只需要一个位用于布尔值,另一个位用于IsNull标志,因此总的存储需求小于一个字节,理论上它可以存储在一个字节中,然而,像往常一样,如果可以分配的最小内存块是8字节(如在64位机器上),那么它仍然需要8字节的内存。

o75abkj4

o75abkj42#

Nullable<T>的大小肯定是依赖于类型的。该结构有两个成员

  • boolean:对于hasValue
  • value:基础值

结构的大小通常Map为4加上类型参数T的大小。

o4hqfura

o4hqfura3#

int? a = 3;
  00000038  lea         ecx,[ebp-48h] 
  0000003b  mov         edx,3 
  00000040  call        78BFD740 
  00000045  nop              
            a = null;
  00000046  lea         edi,[ebp-48h] 
  00000049  pxor        xmm0,xmm0 
  0000004d  movq        mmword ptr [edi],xmm0

看起来第一个dword是值,第二个是null标志。总共8个字节。
奇怪的是,BinaryWritter不喜欢写可空类型。我在想,如果它可以把它压缩得更紧,然后8字节...

hpcdzsge

hpcdzsge4#

.NET(以及大多数其他语言/框架)的默认行为是将结构体字段对齐到其大小的倍数,并将结构体本身对齐到其最大字段大小的倍数。参考:StructLayout
Nullable<T>具有bool标志和T值。由于bool只占用1个字节,因此最大字段的大小是T的大小;与单独的T相比,Nullable将所需的空间加倍。参考:可空源

说明:如果T本身是一个非原始结构体而不是原始类型,则Nullable将增加T内最大原始字段的大小所需的空间,或者递归地增加T的任何非原始字段的大小所需的空间。因此,Nullable<Nullable<bool>>的大小是3,而不是4。

ckocjqey

ckocjqey5#

您可以使用类似于https://www.dotnetperls.com/nullable-memory的代码进行检查。
我得到了以下结果:

  • Int32 4字节
  • Int32? 8字节
  • Int16 2字节
  • Int16? 4字节
  • Int64 8字节
  • Int64? 16字节
  • Byte 1字节
  • Byte? 2字节
  • bool 1字节
  • bool? 2字节
f45qwnt8

f45qwnt86#

int?是一个包含布尔值hasValue和int值的结构体。因此,它的占用空间为5字节。这同样适用于nullable<T>的所有示例:size = sizeof(T)+sizeof(bool)

9njqaruj

9njqaruj7#

可空类型是一个包含正则变量和空状态标志的结构。
对于一个可为空的int,这意味着它包含五个字节的数据,但它当然被填充到完整的单词,所以它使用了八个字节。
您通常可以预期任何可空类型都将比常规类型大四个字节,除了像byte和boolean这样的小类型。

jqjz2hbq

jqjz2hbq8#

32-位和64位机器:

*int==4字节
*int?==8 bytes== 4 for int + 4 for nullable type wrapper.

可空类型 Package 需要4个字节的存储。而整数本身要求每个元素有4个字节。这是一种有效的实现方式。在数组中,许多可空类型存储在连续的内存中。
基于个人测试(.NET Framework 4.6.1,x64,发行版)和-https://www.dotnetperls.com/nullable-memory
此外,如果有趣:why int on x64 equals only 4 bytes?

  • 注意:仅对Nullable<int>有效,Nullable<T>的大小完全取决于类型。*
5gfr0r5j

5gfr0r5j9#

在.NET Framework 4.8上:

List<double?> list1 = new List<double?>();
for (int i=0; i<10000000; i++)
{
  list1.Add( 1 );
}

list1使用262 165 KB

List<double?> list2 = new List<double?>();
for (int i=0; i<10000000; i++)
{
  list1.Add( 2 );
}

list2使用131 093 KB

相关问题