在堆栈上分配对象的好处?

时间:2014-04-16 05:56:40

标签: c# c++ stack heap

成分:

  • 两种语言 - 如C ++和C#
  • 类型方式比仅包含两个成员的Point更复杂(字段xy

在C#中,这种类型将被定义为引用类型,强制它始终在堆上分配它。在C ++中,分配由用法定义,而不是由类型定义定义,因此可以在堆栈上分配它。

这样做的好处是RAII模式,具有在对象超出范围后自动清理数据的效果。在C#中,您必须使用using作为明确的“清理范围”(这也是由于非确定性GC)。

我知道的第二个是速度 - 堆栈访问速度更快。

我的问题是 - 有没有(命名一个就足够了)在堆栈上分配复杂对象的能力(除了RAII和速度除外)(与C ++相比)总是在堆上(如在C#中) )?

真实 - 最好,我正在寻找“永远在堆上”方法不可用的东西,因为RAII毕竟用不同的语法解析。

此问题不涉及C#中的值类型(结构)!这是跨语言比较。

3 个答案:

答案 0 :(得分:3)

  除了RAII和在堆栈上分配复杂对象的能力的速度

之外,是否有任何(命名一个是足够的)其他实际好处

是的,这个比分配速度更重要:访问速度。通过摆脱不必要的间接,您可以获得显着的性能提升。 Herb Sutter最近给了an interesting talk,其中包括他对连续记忆的强烈热爱。他引用的一个示例项目通过使预取器的生活更轻松,性能提高了50倍。 (是的,我们谈论的速度要快50倍,而不是快50%!)

答案 1 :(得分:1)

这不是您问题的真实答案,但它比评论更长。

在C#值类型中分配堆栈并在堆上分配引用类型是一种误解。值类型未定义为堆栈上的内容。这是一个实现细节,而不是设计规范。规范是值按值复制。这并不意味着它们必须存储在堆栈中。可以实现一个根本不使用堆栈的C#编译器。值或引用类型的实例将转到堆栈,堆或寄存器,具体取决于它们是短期还是长期存在。未存储在堆栈中的值类型的示例是

  • 班级中的字段
  • 盒装价值类型
  • 匿名方法的外部变量
  • 迭代器块的外部变量

更多信息我建议阅读Eric Lippert关于此事的帖子:

答案 2 :(得分:1)

堆栈模型与堆+ GC的一个好处是它更具确定性。当然,在实时系统中,衡量一个函数需要多长时间是有用的,而且当一些清理成本在未指定的时间发生时很难。