Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可为空的内存占用量是多少<;T>;_C#_.net_Memory_Nullable - Fatal编程技术网

C# 可为空的内存占用量是多少<;T>;

C# 可为空的内存占用量是多少<;T>;,c#,.net,memory,nullable,C#,.net,Memory,Nullable,int(Int32)的内存占用为4字节。但以下各项的内存占用是什么: int? i = null; 以及: 这是一般的还是类型相关的?一个int?是一个包含布尔值和一个int的结构。因此,它有5个字节的内存占用。这同样适用于可为空的所有实例:size=sizeof(T)+sizeof(bool)我不是100%确定,但我相信它应该是8字节,int32应该是4字节,而且(因为在32位机器上每件事情都必须是4字节对齐的)布尔值的另4个字节,指示是否指定了整数值 注意,多亏了@sensorSmith,

int
Int32
)的内存占用为4字节。但以下各项的内存占用是什么:

int? i = null;
以及:


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

一个
int?
是一个包含布尔值和一个int的结构。因此,它有5个字节的内存占用。这同样适用于可为空的所有实例:
size=sizeof(T)+sizeof(bool)
我不是100%确定,但我相信它应该是8字节,int32应该是4字节,而且(因为在32位机器上每件事情都必须是4字节对齐的)布尔值的另4个字节,指示是否指定了整数值

注意,多亏了@sensorSmith,我现在意识到较新版本的.Net允许将可空值存储在较小的封装外形中(当硬件内存设计允许独立分配较小的内存块时)。在64位机器上,它仍然是8字节(64位),因为这是可以寻址的最小内存块


例如,一个可空值只需要布尔值的一个位,IsNull标志的另一个位,因此总存储需求少于一个字节。理论上,它可以存储在一个字节中。但是,与往常一样,如果可以分配的最小内存块是8个字节(如在64位机器上),然后它仍然需要8字节的内存。

可空类型是一个包含正则变量和空状态标志的结构

对于一个可为null的int,这意味着它包含五个字节的数据,但它当然是填充到完整的单词中的,所以它使用了八个字节


您通常可以预期任何可空类型都会比常规类型大四个字节,但byte和boolean之类的小类型除外。

可空类型的大小肯定取决于类型。该结构有两个成员

  • 布尔值:用于hasValue
  • 值:用于基础值
结构的大小通常映射为4加上类型参数T的大小

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 智力?a=3; 000000 38 lea ecx,[ebp-48h] 000000 3B mov edx,3 00000040拨打78BFD740 00000045无 a=零; 00000046 lea电子数据交换[ebp-48h] 00000049像素或xmm0,xmm0 000000 4D movq mmword ptr[edi],xmm0 看起来第一个dword代表值,第二个代表null标志。总共8个字节


奇怪的是,BinaryWriter不喜欢编写可为null的类型。我想知道它是否可以将其压缩到比8字节更紧的位置…

32位和64位机器:

  • int=4字节
  • int?=8字节==4表示int+4表示可空类型包装器
可空类型包装需要4字节的存储空间。整数呢 每个元素本身需要4个字节。这是一个有效的方法 实施在数组中,许多可为null的类型存储在 连续存储器

基于个人测试(.NET Framework 4.6.1,x64,发行版)和-

此外,如果有兴趣:


注意:这仅适用于
Nullable
Nullable
的大小完全取决于类型。

您可以使用一些类似于

我得到了以下结果:

  • Int32
    4字节
  • Int32?
    8字节
  • Int16
    2字节
  • Int16?
    4字节
  • Int64
    8字节
  • Int64?
    16字节
  • Byte
    1字节
  • Byte?
    2字节
  • bool
    1字节
  • bool?
    2字节
NET(以及大多数其他语言/框架)的默认行为是将结构字段与其大小的倍数对齐,并将结构本身与最大字段大小的倍数对齐。参考:

Nullable
具有布尔标志和T值。因为bool只需要1字节,所以最大字段的大小是T的大小;与单独使用T相比,Nullable所需的空间增加了一倍。参考:


澄清:如果T本身是非基本结构而不是基本类型,Nullable会增加T中最大基本字段大小所需的空间,或者递归地增加T的任何非基本字段大小所需的空间。因此,
Nullable
的大小是3,而不是4。

很好。我不太了解数据是如何打包在一起的。在任何情况下,数据中是否有值或值是否为“null”都无关紧要。无论如何,它将占用相同的字节数。64位机器有一个64位(8字节)宽的总线,因此,据我所知,每次数据获取(或写入)都会从内存中返回64位(8字节)。装箱后大小再次不同,因为Nullable消失,所以它要么为null,要么为已装箱的int。布尔值不是4字节
sizeof(bool)
返回1,因此
Nullable
将占用5个字节。我不认为将填充添加到结构的末尾。@Virtlink true,但由于大部分时间内存对齐,布尔值实际上需要4个字节。例如,如果数组为Nullable.sizeof,则会出现错误,建议改用System.Runtime.InteropServices.Marshal.sizeof。但是对于double,它返回8个字节?然后我试着写了一个双?值转换为字节数组,结果显示使用了16个字节。是我错了,还是效率太低了?7字节用于对齐?在我前雇主的一个网络项目中,我们会将其编码为33位到数据流中。33位不能很好地切割:)我知道。我们采用了位对齐,有时甚至更高级的打包,比如将3个三态(27种可能)编码为5位。 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