【问题标题】:Why Java and C# does not allow the creation of objects on the stack?为什么 Java 和 C# 不允许在堆栈上创建对象?
【发布时间】:2015-03-28 07:07:48
【问题描述】:

为什么我可以使用 C++ 在堆栈上创建对象,但使用其他编程语言(如 Java 或 C#)却无法做到这一点?

【问题讨论】:

  • 因为语言的设计者并没有给你一个方法来做到这一点。 (实际上,Java 至少没有分配对象的概念;对象只是存在
  • @immibis - 逃逸分析至少在理论上可以在堆栈本身上分配对象。
  • @TheLostMind 我认为问题不在于 JIT 优化。
  • C++ 没有明确使用堆栈的概念,而是定义了不同类型的对象生命周期。所以在这种情况下,您的意思是自动存储
  • @juanchopanza - 您的评论实际上回答了 OP 的问题。

标签: java c# c++ computer-science


【解决方案1】:

我不知道我的回答是否抓住了语言设计者这样做的原因,但考虑到我做了很多 C++ 和 Java 编程,我的回答是:“因为没有需要”。

在 Java 中,我不关心对象的创建位置

C++ 中“堆上的对象”和“栈上的对象”之间的主要区别在于,在后一种情况下,对象在超出范围时会自动销毁。在 Java 中,即使对象是在堆上创建的,情况也是如此,因为 Java 有一个垃圾收集器并检查引用是否“超出范围”(从某种意义上说,程序的任何部分都没有持有对对象)。

所以在 Java 中,对象是在堆上创建的,但从“C++”的角度来看,它们的行为就像是在堆栈上创建的一样。

PS:另一个方面可能是:在 C++ 中,堆栈大小是/可以限制的(远大于堆大小),因此在堆栈上创建大量对象可能是个问题。

【讨论】:

  • 此外,转义分析通常确实确​​实将 Java 对象放入堆栈。不过,没有人在乎 :)
【解决方案2】:

原因很简单:在 C++ 中,您必须自己管理所有这些内存分配。对象在哪里分配,什么时候释放。

在 Java 和 C#(实际上是 .NET)中,这要容易得多。对象在堆上分配,并在不再需要时进行垃圾收集。这消除了一系列问题(内存泄漏和访问释放的对象)

【讨论】:

  • 您几乎不必在 C++ 中自己“管理”内存分配,除非您真的想这样做。而且通常情况下,您不想这样做。
  • 是的,有趣的是人们说您必须在 C++ 中手动管理内存,并将其列为该语言的一个缺点(并不是说 ruediste 正在这样做)。实际上,您可以选择手动管理内存的选项。许多其他语言拒绝您的选项,并且您当然不需要使用的选项。这是积极的,而不是消极的。
  • 我也不同意手动管理内存。RAII 的存在是有原因的。std::unique_ptrstd::shared_ptr 这样的容器也是如此。析构函数的存在是有原因的。
猜你喜欢
  • 2016-02-27
  • 2020-04-09
  • 2010-12-08
  • 2016-12-28
  • 1970-01-01
  • 2017-09-09
  • 2020-10-27
  • 2014-11-12
  • 2016-10-15
相关资源
最近更新 更多