public class A
{
public static void Main(string[] args)
{
int num = 13; // It stores in Stack and takes 4 bytes
object obj = 13; // Where it is Stored (Stack or Heap)?
//How much size obj require?
}
}
Run Code Online (Sandbox Code Playgroud)
我只想知道 obj 所需的额外位,为什么?
首先帮助解释“为什么”,来自 C# 5 规范:第 4.3.1 节装箱转换
对不可空值类型的值进行装箱的实际过程最好通过想象一个通用装箱类的存在来解释,该类的行为就像声明如下:
Run Code Online (Sandbox Code Playgroud)sealed class Box<T>: System.ValueType { T value; public Box(T t) { value = t; } }装箱 T 类型的值 v 现在包括执行表达式 new Box(v),并将结果实例作为类型 object 的值返回。因此,声明
Run Code Online (Sandbox Code Playgroud)int i = 123; object box = i;概念上对应于
Run Code Online (Sandbox Code Playgroud)int i = 123; object box = new Box<int>(i);
要回答它是存储在堆栈上还是堆上,答案是两者兼而有之。请参阅MSDN 上的装箱和拆箱。
考虑以下值类型变量的声明:
Run Code Online (Sandbox Code Playgroud)int i = 123;以下语句隐式地对变量 i 应用装箱操作:
Run Code Online (Sandbox Code Playgroud)// Boxing copies the value of i into object o. object o = i;此语句的结果是在堆栈上创建对象引用 o,该对象引用在堆上引用 int 类型的值。该值是分配给变量 i 的值类型值的副本。下图说明了 i 和 o 两个变量之间的差异。
所以在堆栈上sizeof(Object)存储了字节,在堆上sizeof(int)存储了 + 类开销。
我找不到任何关于开销有多大的好的文档,它的大小很可能是 8 到 16 个字节。
根据这篇文章,每个对象的标头在 32 位系统上为 8 个字节,在 64 位系统上为 16 个字节。这意味着您的装箱 int 将在堆上占用12 个字节,在 32 位系统上占用堆栈上的 4 个字节引用,在 64 位系统上占用堆上的 20 个字节和堆栈上的 8 个字节。然而,根据@Hans Passant 的评论,对象必须在 32 位模式下对齐到 4 字节的倍数,在 64 字节中对齐到 8 字节的倍数,这将使64 位版本占用 24 字节。
应该注意的是,这是一个实现细节,将来可能会发生变化。一般来说,你会关心这个很奇怪。在处理值类型时,CPU 时间通常比内存大得多,因为装箱会给 GC 带来负载,并且需要额外的操作才能使用对象。
| 归档时间: |
|
| 查看次数: |
565 次 |
| 最近记录: |