Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java和C++;关于堆栈展开问题 据我所知,在一个未被排除的异常情况下,C++立即破坏本地变量,java释放引用,剩下的则留给垃圾回收器。_Java_C++_Stack Unwinding - Fatal编程技术网

Java和C++;关于堆栈展开问题 据我所知,在一个未被排除的异常情况下,C++立即破坏本地变量,java释放引用,剩下的则留给垃圾回收器。

Java和C++;关于堆栈展开问题 据我所知,在一个未被排除的异常情况下,C++立即破坏本地变量,java释放引用,剩下的则留给垃圾回收器。,java,c++,stack-unwinding,Java,C++,Stack Unwinding,是这样吗?java和C++在这个问题上的区别究竟是什么?换句话说,在堆栈展开问题上,这两种语言中哪种被认为更好 堆栈展开是专门调用调用链上所有完整构造对象的析构函数,直到捕获异常为止 Java根本没有堆栈展开——如果抛出异常,它不会对对象做任何事情。您必须自己在catch和finally块中处理对象。这主要是为什么C引入的——它们简化了调用IDISPOSIGABLE .AddioTeo(),但这又不是C++堆栈展开的完全替代。 你是非常正确的,C++以相反的顺序破坏所有局部变量,当它退出堆栈上的

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

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


Java根本没有堆栈展开——如果抛出异常,它不会对对象做任何事情。您必须自己在
catch
finally
块中处理对象。这主要是为什么C引入的——它们简化了调用IDISPOSIGABLE .AddioTeo(),但这又不是C++堆栈展开的完全替代。

你是非常正确的,C++以相反的顺序破坏所有局部变量,当它退出堆栈上的每个函数时-就像您正在以编程方式执行return一样-并退出

main()

我会为此感到愤怒,但是

在堆栈展开方面,C++无疑比Java要好——这是不争的事实。C++对象析构函数一直在备份堆栈,直到达到捕获点,沿着一条优雅的方式释放所有托管资源。 正如您所说,Java将所有这些都交给了非确定性垃圾收集器(最坏的情况)的摆布,或者交给了任何显式构建的最终块(因为Java不支持真正的RAII)。也就是说,所有的资源管理代码都掌握在每个类的客户机手中,而不是应该掌握在类设计器手中


,在C++中,如果你仔细确保析构函数本身不发出异常,则堆栈展开机制只能正常运行。一旦您有两个活动异常,您的程序

abort()
将不通过go(当然也不触发任何剩余的析构函数)。

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

主观-定义“更好”。Java实现了一个适当的垃圾收集器,因此从理论上讲,您不必担心对象不会破坏它在堆栈上创建的所有内容。C++假设你很小心,java实现内存垃圾收集器。临时文件不会被垃圾收集,因此可能会因堆栈展开而泄漏。另一方面,在C++堆栈中解散调用析构函数,这除内存清理外,还可以清理临时文件和其他资源。所以java java C++更容易,C++更灵活,是一个标准的工程折衷。@ MsAlter:+1,因为它阐明了C++和Java在资源处理上的根本区别。Trime:但是,C++中的智能指针也可以自动地销毁堆分配的对象。实际上,它们的工作方式完全相同。堆栈展开调用它们的析构函数,它们的析构函数依次销毁相应的堆分配对象。是的,这就是它们的实现方式。我的意思是它们的工作方式不同,因为使用智能指针时,您不需要太多的注意来避免内存泄漏。我想sharptooth想告诉您的是,您也应该在讨论中提到智能指针。类似的:对象仍然在堆上,但是基于堆栈的智能指针将尽快释放它。@ Mnementh:除了由析构函数对象拥有的堆对象之外。@ MnEnthEn:在C++中,你必须有纪律:堆分配由智能指针保存,句号。结束内存管理问题。对不起,我不是有意对java咆哮,但有时我觉得他们通过删除C++的所有好部分来创建“更好C++”。胡说他们关心的是应用程序不会崩溃,这在Java中显然更容易实现;他们关心的是性能,这可能有点困难,但肯定不是不可能。GC暂停的问题通常可以通过调整JVM的GC选项来解决。@Drew Hall:自动限制到智能指针?为什么你要删去C++的好部分?关于RAII,如果Java中的资源(比如db连接)有问题,为什么它没有一个类似于析构函数的机制,在垃圾收集器收集对象时调用它呢。这样,我们将保证资源将被关闭,无论何时。对吗?在这里问一个问题可能更好:为什么Java没有一个类似于析构函数的机制,在垃圾收集器收集对象时调用它?这样,我们将保证关闭我们的资源;无论何时,因为我们对处理内存泄漏更感兴趣。