代码之家  ›  专栏  ›  技术社区  ›  Feyyaz Phill Pafford

Java和C++在栈解卷中的应用

  •  11
  • Feyyaz Phill Pafford  · 技术社区  · 14 年前

    据我所知,在出现异常的情况下,C++立即销毁本地变量,Java释放引用并将其余部分留给垃圾收集器。

    是这样吗?Java和C++在这个问题上的区别究竟是什么?换句话说,这两种语言中哪一种在堆栈展开问题上被认为更好?:)

    4 回复  |  直到 14 年前
        1
  •  9
  •   Drew Hall    14 年前

    我会为此火冒三丈但是…

    在堆栈展开前,C++比Java好得多,没有竞争。C++对象析构函数一直在备份堆栈,直到达到捕获点为止,顺畅地释放所有托管资源。

    正如你所说的,Java将所有这些都放在非确定性垃圾收集器(最坏的情况)的摆布下,或是用任何精心设计的最后一个块来清除代码(因为Java不支持真实RAII)。也就是说,所有的资源管理代码都在每个类的客户端手中,而不是在类设计器的手中。

    也就是说,在C++中,如果您仔细确保析构函数本身不发出异常,则堆栈展开机制只能正常运行。一旦有两个活动异常,您的程序 abort() 没有通过go(当然也没有发射任何剩余的析构函数)。

        2
  •  5
  •   sharptooth    14 年前

    堆栈展开特别是调用调用链上所有完全构造的对象的析构函数,直到捕获异常为止。

    Java简单地没有堆栈展开——如果抛出异常,它对对象没有任何作用。你必须自己处理这些东西 catch finally 阻碍。这就是为什么C using statements -它们简化了调用IDISPosial.Advices(),但又不是完全替换C++堆栈展开。

        3
  •  2
  •   quamrana    14 年前

    您完全正确,C++会破坏所有本地变量,因为它退出堆栈上的每个函数——就像您在编程上执行返回和退出一样。 main() .

        4
  •  2
  •   Mnementh    14 年前

    对于堆栈,这两种方法都是一样的:它们为您留下的异常块释放堆栈。在Java中,所有的原始类型(int,双等)都被直接保存,此时这个类型的局部变量被释放。所有对象都是通过局部变量中的引用保存的,因此引用将被删除,但对象本身保留在堆中。如果这是对该对象的最后一次引用,则在下一次垃圾回收时释放它们。如果C++是堆上创建的对象,并且本地变量保持指针,堆上的对象不会自动释放,它们将永远留在堆上(是的,内存泄漏)。如果在堆栈中保存了对象,则调用析构函数(并可能释放堆中的其他引用对象)。