通用列表是存储在 C# 中的堆栈还是堆中?

Posted

技术标签:

【中文标题】通用列表是存储在 C# 中的堆栈还是堆中?【英文标题】:Are Generic lists stored on the stack or the heap in C#? 【发布时间】:2011-04-11 18:32:20 【问题描述】:

通用列表是存储在栈上还是堆上?

示例

//List of Ints
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(20);

myInts 是存储在栈上还是堆上?如果我将int 添加到列表中,是否会进行装箱或拆箱?

【问题讨论】:

【参考方案1】:

List&lt;T&gt; 是一个引用类型。它在内部使用T[]。数组是引用类型。引用类型的实例存储在堆上。由于您示例中的列表是List&lt;int&gt;,因此它只能容纳ints,并且不会发生装箱。如果您需要将值类型视为引用类型,则会发生装箱。

【讨论】:

嗨,Brain,你能解释一下这个 List 的内存分配究竟是如何发生的吗?这是否意味着添加的 Ints 是值类型,因此它们将存储在堆栈中,然后 myInts 的引用将指向何处? @Tanuja:列表本身及其所有内容将存储在堆上。您的引用将指向堆上的列表实例。如果值类型是引用类型的一部分(例如类的 int 字段)或存储在数组中,则值类型将存储在堆中。【参考方案2】:

在 C# 或 .NET 中创建对象时没有“堆”或“堆栈”的概念。虽然列表存储在堆上,但这实际上是 CLR 如何管理其内存的实现细节。

这里没有装箱或拆箱。这就是使用泛型List 类优于非泛型ArrayList 的优势。当创建List&lt;int&gt; 的新实例时,就好像您编写了一个仅用于管理int 列表的类。当从列表中检索到 int 时,甚至没有任何演员在幕后进行。

【讨论】:

这可能是一个实现细节,但语言规范确实提到引用类型的实例存储在堆上,而值类型则没有。 blogs.msdn.com/b/ericlippert/archive/2009/04/27/… @Brian,但这只是故事的一部分。引用类型对象的值类型字段存储在哪里?与对象。更大的一点是,在假设的未来版本中,这一切都可能发生变化。 @Anthony:我知道。我并没有试图解释事物是如何存储的。我只是多次指出语言规范涵盖了这一点。请注意,我没有说值类型存储在堆栈中,只是说它们不会产生堆分配,这是规范中使用的措辞。【参考方案3】:

对于像int 这样的结构,通用列表正在变得专门化,因此不需要装箱/拆箱。

请注意,值本身存储在 List 的支持数组中。

【讨论】:

以上是关于通用列表是存储在 C# 中的堆栈还是堆中?的主要内容,如果未能解决你的问题,请参考以下文章

存储在堆栈或堆中的对象方法?

java---堆栈常量池的存储数据

堆栈/堆中的向量元素?长输入,C++

C#中equal与==的区别

值类型何时存储在堆栈(C#)中?

数组是如何存储在内存中的?