c# - .NET 非/通用列表存储在堆栈还是堆上?

标签 c# list generics

我想知道以下列表存储在堆栈或堆上的位置?

  1. 值类型的非泛型列表

    int[] strArray = { 1, 2, 3 };
    
  2. 引用类型的非泛型列表

    Person[] personArray = new Person[1];
    personArray[0] = new Person();
    
  3. 值类型的通用列表

    List<int> moreInts = new List<int>();
    moreInts.Add(10);
    
  4. 引用类型的通用列表

    List<Person> morePeople = new List<Person>();
    morePeople.Add(new Person ("Frank", "Black", 50));
    

最佳答案

  1. 字符串不是值类型
  2. 数组不是值类型
  3. 列表不是值类型(内部使用数组)

理论上两者都可以存储在堆栈或堆上(或者完全不同的东西!),这不是规范的一部分。实际上,堆栈仅用于范围内的事物,并且为了简化确保引用在范围内,它通常只将值类型放在堆栈上,因为这些很容易验证。然而,它们也可以存储在寄存器中。由 JIT 编译器来决定。

在不安全代码中,您可以在堆栈上显式分配一些指针,但这仅限于不安全代码中。除此之外,这取决于 JIT 编译器的实现。但是,在当前版本中,您可以非常确定所有无法验证其生命周期是否足够有限的内容都将被放置在堆上。这里的关键是范围,而不是引用类型还是值类型。只是值类型通常很容易验证:)

如果你非要考虑是在堆上还是在栈上,那很可能就是在堆上。无论如何,重点是“你不在乎”。仅关心您是否有性能分析数据来支持您确实存在与此相关的问题这一事实。

记住 - 堆栈、堆、寄存器...所有这些都只是 .NET 托管内存模型中的实现细节。

关于c# - .NET 非/通用列表存储在堆栈还是堆上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22687108/

相关文章:

list - React Native SectionList 有无法理解的流类型错误

c# - 反射生成的类型和泛型

c# - EF7 迁移 - 实体类型 '' 对应的 CLR 类型不可实例化

c# - TextWrapping 属性设置为 WrapWholeWords 时获取参数不正确错误?

java - 比较 2 个列表中的元素时如何避免 O(N^2)?

c# - 如何显示目录中的文件

Java - 当方法名称不同时将代码提取到泛型方法

c# - 为接口(interface)定义方法定义

c# - 避免调试器因线程中捕获的异常而停止

generics - 有没有一种方法可以实现与泛型相结合的 `as`语义?