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?
}
}
我只是想知道obj所需的额外位以及为什么?
答案 0 :(得分:4)
首先帮助解释"为什么",来自C#5规范:第4.3.1节拳击转换
装箱非可空值类型的值的实际过程是 最好通过想象一个通用拳击课的存在来解释, 其行为就像声明如下:
sealed class Box<T>: System.ValueType { T value; public Box(T t) { value = t; } }
现在,对类型T的值v的装箱包括执行表达式 new Box(v),并将结果实例作为类型值返回 宾语。因此,陈述
int i = 123; object box = i;
在概念上对应于
int i = 123; object box = new Box<int>(i);
要回答它是存储在堆栈还是堆上,答案都是。请参阅MSDN上的Boxing and Unboxing。
考虑以下值类型变量的声明:
int i = 123;
以下语句隐式应用了装箱操作 变量i:
// Boxing copies the value of i into object o. object o = i;
该语句的结果是在on上创建一个对象引用o stack,在堆上引用int类型的值。这个 value是分配给变量i的值类型值的副本。 两个变量i和o之间的差异如图所示 下图
因此在堆栈上存储了sizeof(Object)
个字节,并且在堆上存储了sizeof(int)
+类开销。
我找不到任何关于开销有多大的好文档,它最有可能是8到16个字节。
答案 1 :(得分:4)
根据this article,每个对象的标题在32位系统上是8个字节,在64位系统上是16个字节。这意味着你的盒装int将在堆上占用 12个字节,在32位系统上占用堆栈上的4个字节,在堆上占用20个字节,在64位系统上占用8个字节。但是根据@Hans Passant的评论,对象必须在32位模式下与4个字节的倍数对齐,在64个字节中对应8个字节的倍数,这将使 64位版本占用24个字节
应该注意,这是一个实现细节,将来可能会发生变化。一般来说,你会关心这一点很奇怪。在处理值类型时,CPU时间通常比内存大得多,因为装箱会在GC上加载并需要额外的操作才能使用该对象。