为什么Java没有像C++这样的析构函数?

Abh*_*ain 7 java destructor

Java有自己的垃圾收集实现,因此它不需要像C++这样的任何析构函数.这使得Java开发人员懒得实现内存管理.

我们仍然可以使用析构函数和垃圾收集器,开发人员可以在其中释放资源并且可以节省垃圾收集器的工作.这可能会提高应用程序的性能.为什么Java不提供任何析构函数的机制?

开发人员无法控制GC,但他/她可以控制或创建对象.那么为什么不给它们破坏物体的能力呢?

Jon*_*eet 55

你断言"垃圾收集非常昂贵" - 你能用证据支持吗?垃圾收集肯定不是免费的,但现代垃圾收集器非常好.

请注意,GC能够高效的方法之一是它知道它是进行内存分配和释放(对于托管对象)的唯一方法.允许开发人员明确释放对象可能会妨碍这种效率.您还需要担心如果开发人员试图"使用"一个释放的对象会发生什么:

Foo f = new Foo();
Foo g = f;
free(f); // Or whatever
System.out.println(g.toString()); // What should this do?
Run Code Online (Sandbox Code Playgroud)

您是否建议每个对象都应该有一个额外的标志"是否已明确释放",需要在每次取消引用时进行检查?说实话,这就像是一场灾难.

你是对的 - 它确实允许Java开发人员在这方面懒惰.这是好事.IDE也允许开发人员变得懒惰 - 高级语言也是如此.等待内存分配的懒惰使管理环境中的开发人员能够花费精力来解决业务问题而不是内存管理.

  • `free`也不是*free*. (25认同)
  • 你做了一个很好的例子,它允许Java开发人员在这方面懒惰,所以他们可以把时间花在其他事情上.但是你没有回答这个部分,为什么它会自愿地_forbidden_​​,故意在需要时破坏一个物体. (4认同)
  • @JamesB"我选择一个懒惰的人来做一份艰苦的工作.因为一个懒惰的人会找到一个简单的方法去做." - Billus Gatus. (2认同)

Ste*_*n C 22

垃圾收集非常昂贵.

事实上,对于复杂的应用程序,垃圾收集的性能基于malloc/的手动存储管理相比具有竞争力free.Benjamin Zorn有一篇经典论文清楚地证明了这一点.在本文中,Zorn描述了他如何修改一些大型密集型应用程序以使用保守的垃圾收集器而不是mallocfree.然后他对应用程序的原始版本和修改版本进行了基准测试.结果是相当的表现.

本文于1993年在软件实践和经验中发表.如果你还没有阅读,你没有资格就垃圾收集的"低效率"发表声明.

请注意,这项研究是使用1993年代的老式保守垃圾收集器完成的.一个保守的收藏家是没有任何压缩的标记扫描; 即非垃圾对象不移动.后者意味着为新对象分配空间同样缓慢而复杂malloc.相比之下,现代垃圾收集器(例如Java 6/7)是分代式复制收集器,效率更高.由于复制压缩剩余的非垃圾对象,因此分配速度更快.这使GC更具竞争力......如果有人能找到比较的方法.


开发人员无法控制GC,但他/她可以控制或创建对象.那么为什么不给它们破坏物体的能力呢?

这取决于你所谓的"破坏"是什么意思.

  • 在Java中,您可以分配null.在某些情况下,这可能加速对象的破坏.

  • 在Java中,你可以使用终结器和Reference类型来注意一个对象即将被销毁......以及它的一些东西.

  • 在Java中,您可以close()在任何对象上定义(或等效)方法,并让它执行适当的操作.然后明确地调用它.

  • 在Java 7中,您可以使用"try with resources"构造来自动调用close()作用域出口上的资源.

但是,您不能立即删除Java对象.不允许这样做的原因是它允许程序创建悬空引用,这可能导致堆损坏和随机JVM崩溃.

这不是Java方式.理念是编写可靠的程序比效率更重要.虽然Java的某些方面不遵循这一点(例如线程),但没有人想要随机JVM崩溃的可能性.

  • @Abhishek:如果你*期待*一个对你的断言提出异议的答案,你为什么要把它作为开头的断言包括在内?为什么不问"垃圾收集是否昂贵?" 国际合作组织(IMO)认为这不会引发争议. (2认同)

Tad*_*pec 7

C++析构函数不是一种破坏对象的方法 - 它是一组在对象被破坏时要完成的操作.在Java中,您无法控制对象被破坏的时间(它们甚至可能永远不会被破坏),因此强烈建议不要在对象破坏时执行任何重要代码(尽管可能 - finalize方法).如果您不是要求析构函数,而是要求明确销毁给定对象的方法,那么您将邀请悬空引用到您的代码中.他们不受欢迎.

  • C++没有给你"无法控制对象被破坏的时间".C++使用确定性终结.删除对象时,会立即调用其析构函数,然后立即释放其存储空间.没有C++ GC.我不是说这必然是一件好事,而是C++的工作方式. (4认同)
  • @andyjohnson:要么你误会了我,要么我的语法被打破了.无论如何,我试图解决它.在Java中无法控制对象被销毁的时间.在C++中,您可以完全控制它(模拟关于临时生命的复杂规则). (2认同)

use*_*421 5

这使得Java开发人员懒得实现内存管理.

不,它释放它们以执行有用的工作.

而垃圾收集非常昂贵.

相比什么?事实呢?数据?这段话你已经过了20年了.仅仅采用Java就有效地反驳了这种争论.

这可能会提高应用程序的性能.

或不.你有一些事实可以引用吗?

那么为什么不给它们破坏物体的能力呢?

因为它不是必需的?