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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2606523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:00:28  来源:igfitidea点击:

Why does Java not have any destructor like C++?

javadestructor

提问by Abhishek Jain

Java has its own garbage collection implementation so it does not require any destructor like C++ . This makes Java developer lazy in implementing memory management.

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

Still we can have destructor along with garbage collector where developer can free resources and which can save garbage collector's work.This might improves the performance of application. Why does Java not provide any destructor kind of mechanism?

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

Developerdoes not have control over GC but he/she can control or create object. Then why not give them ability to destruct the objects?

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

回答by Jon Skeet

You're asserting that "garbage collection is very expensive" - could you back that up with evidence? Garbage collection is certainly not freebut modern garbage collectors are very good.

你断言“垃圾收集非常昂贵”——你能用证据来支持吗?垃圾收集当然不是免费的,但现代垃圾收集器非常好。

Note that one of the ways in which the GC is able to be efficient is that it knowsit's the only thing doing memory allocation and deallocation (for managed objects). Allowing a developer to explicitlyfree an object could hamper that efficiency. You'd also need to worry about what would happen if a developer tried to "use" a freed object:

请注意,GC 能够高效的方法之一是它知道它是唯一进行内存分配和释放(对于托管对象)的事情。允许开发人员显式释放对象可能会影响该效率。您还需要担心如果开发人员试图“使用”释放的对象会发生什么:

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

Are you proposing that each object should have an extra flag for "has this explicitly been freed" which needs to be checked on every dereference? This feels like a recipe for disaster, to be honest.

您是否建议每个对象都应该有一个额外的标志来表示“是否已明确释放”,每次取消引用时都需要检查该标志?老实说,这感觉就像是灾难的秘诀。

You're right though - it does allow Java developers to be lazy in this area. That's a good thing. IDEs allow developers to be lazy, too - as do high-level languages, etc. Laziness around memory allocation allows developers in managed environments to spend their energy worrying about business problems rather than memory management.

您是对的 - 它确实允许 Java 开发人员在这方面变得懒惰。这是好事。IDE 也允许开发人员变得懒惰——就像高级语言等一样。围绕内存分配的惰性允许托管环境中的开发人员将精力花在担心业务问题而不是内存管理上。

回答by Stephen C

Garbage Collection is very expensive.

垃圾收集非常昂贵。

In fact, for complex applications, the performance of garbage collection is competitive withmanual storage management based on malloc/ free. There is a classic paper by Benjamin Zornthat clearly demonstrates this. In this paper, Zorn describes how he modified some large heap intensive applications to use a conservative garbage collector instead of mallocand free. Then he benchmarked the original and modified versions of the applications. The result was comparable performance.

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

This paper was published in Software Practice and Experience in 1993. If you haven't read it, you are not qualified to make pronouncements on the "inefficiency" of garbage collection.

这篇论文发表于1993年的Software Practice and Experience,如果你没看过,你没有资格对垃圾收集的“低效率”发表意见。

Note that this research was done with a 1993-vintage conservativegarbage collector. A conservative collector is mark-sweep without any compaction; i.e. non-garbage objects don't move. The latter means that allocation of space for new objects is as slow and complicated as malloc. By contrast, modern garbage collectors (e.g. Java 6/7 ones) are generational copying collectors which are much more efficient. And since copying compacts the remaining non-garbage objects, allocation is much faster. This makes GC even more competitive ... if one could find a way to do the comparison.

请注意,这项研究是使用 1993 年的旧式保守垃圾收集器完成的。保守收集器是标记清除而不进行任何压缩;即非垃圾对象不移动。后者意味着为新对象分配空间与malloc. 相比之下,现代垃圾收集器(例如 Java 6/7 的)是更高效的分代复制收集器。由于复制压缩了剩余的非垃圾对象,分配速度要快得多。这使得 GC 更具竞争力……如果有人能找到一种方法来进行比较的话。



Developer does not have control over GC but he/she can control or create object. Then why not give them ability to destruct the objects?

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

It depends on what precisely you mean by "destruct".

这取决于您所说的“破坏”究竟是什么意思。

  • In Java, you do have the ability to assign null. In some circumstances this may hasten the destruction of an object.

  • In Java, you can use finalizers and Referencetypes to notice that an object is about to be destroyed ... and so something about it.

  • In Java, you can define a close()(or equivalent) method on any object and have it do something appropriate. Then call it explicitly.

  • In Java 7, you have the "try with resources" construct for automatically calling close()on the resources on scope exit.

  • 在 Java 中,您确实可以将null. 在某些情况下,这可能会加速对象的销毁。

  • 在 Java 中,您可以使用终结器和Reference类型来通知对象即将被销毁……等等。

  • 在 Java 中,您可以close()在任何对象上定义一个(或等效的)方法并让它做一些适当的事情。然后显式调用它。

  • 在 Java 7 中,您有“尝试资源”构造,用于close()在范围退出时自动调用资源。

However, you can't cause a Java object to be deleted NOW. The reason this is not allowed is that it would allow a program to create dangling references, which could lead to corruption of the heap and random JVM crashes.

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

That is NOT the Java way. The philosophy is that writing reliable programs is more important than efficiency. While certain aspects of Java don't follow this (e.g. threading) nobody wants the possibility of random JVM crashes.

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

回答by Tadeusz Kopec

The C++ destructor is not a way to destruct objects - it's a set of operation that are to be done when the object is destructed. In Java you have no control on the time when objects are destructed (they may be even never destructed), so putting any important code to be executed at object destruction is strongly discouraged (although possible - finalizemethod). If you ask not for a destructor but for a way to explicitly destroy given object, you are inviting dangling references into your code. They are not welcome.

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

回答by user207421

This makes Java developer lazy in implementing memory management.

这使得 Java 开发人员在实现内存管理方面变得懒惰。

No, it releases them to perform useful work.

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

And Garbage Collection is very expensive.

并且垃圾收集非常昂贵。

Compared to what? Facts? Figures? You're about 20 years out of date with that remark. The take-up of Java alone effectively disproves that contention.

与什么相比?事实?数据?你这句话已经过时了大约 20 年。仅采用 Java 就有效地反驳了这种争论。

This might improves the performance of application.

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

Or not. Did you have some facts to adduce?

或不。你有一些事实要举出吗?

Then why not give them ability to destruct the objects?

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

Because it's not required?

因为不需要?

回答by quantum

Destructors are called when the object is destroyedin C++, not to destroythe object. If you want to guarantee cleanup, make the user call a Destroy method or similar.

析构函数在 C++中销毁对象时调用的,而不是销毁对象。如果要保证清理,请让用户调用 Destroy 方法或类似方法。

回答by fredoverflow

The C++ destructor is not a way to destruct objects - it's a set of operation that are to be done when the object is destructed.

C++ 析构函数不是一种破坏对象的方法——它是一组在对象被破坏时要完成的操作。

I think you are confusing terminology. Here is how I see it:

我认为你混淆了术语。这是我的看法:

createobject = first allocate memory, then constructvia constructor

创建对象=第一分配内存,然后构造通过构造

destroyobject = first destructvia destructor, then deallocate memory

销毁对象=第一自毁经由析构函数,然后释放内存

How the memory is allocated and deallocated depends. If you use newand delete, the memory management is done by void* operator new(size_t)and void operator delete(void*).

如何分配和释放内存取决于。如果使用newand delete,则内存管理由void* operator new(size_t)and完成void operator delete(void*)

回答by Janusz

If you know you don't some big objects anymore just set the references to them to null. This could maybe speed up the garbage collection of these objects.

如果你知道你不再使用一些大对象,只需将它们的引用设置为 null。这可能会加速这些对象的垃圾收集。

回答by A Fog

A C++ destructor is useful for freeing anyresources owned by the object, not only memory. It may be files, sockets, mutexes, semaphores, or any other resource handles. Using a destructor is a smart way of preventing resource leaks. Wrap the resource handling in a C++ class and make a destructor that frees any allocated resources. I don't see any such method in Java. You have to explicitly free the resource, and this can be tricky if there are many possible exit paths.

C++ 析构函数可用于释放对象拥有的任何资源,而不仅仅是内存。它可能是文件、套接字、互斥体、信号量或任何其他资源句柄。使用析构函数是防止资源泄漏的聪明方法。将资源处理包装在一个 C++ 类中,并创建一个释放任何分配资源的析构函数。我在 Java 中没有看到任何这样的方法。您必须明确释放资源,如果有许多可能的退出路径,这可能会很棘手。

回答by Kowsigan Atsayam

No, java does not support destructors. All freeing the memory task is done by GARBAGE COLLECTOR.

不,java 不支持析构函数。所有释放内存的任务都是由 GARBAGE COLLECTOR 完成的。

Java has it's own memory management feature using garbage collector. When you use finalize() the object becomes available for garbage collection and you don't need to explicitly call for the destructor. C# and Java don't want you to worry about destructor as they have feature of garbage collection.

Java 有自己的内存管理功能,使用垃圾收集器。当您使用 finalize() 时,该对象可用于垃圾收集,并且您不需要显式调用析构函数。C# 和 Java 不希望您担心析构函数,因为它们具有垃圾收集功能。

Java is a bytecode language, it has very strong garbage detection. If you were to allow people to define their own destructors it is likely that they might make some mistakes. By automating the process, Java intends to prevent those mistakes.

Java 是一种字节码语言,它具有很强的垃圾检测能力。如果你允许人们定义他们自己的析构函数,他们很可能会犯一些错误。通过自动化该过程,Java 旨在防止这些错误。

回答by cletus

You do have the ability to control object destruction in Java. It simply uses a different idiom:

您确实有能力在 Java 中控制对象销毁。它只是使用了不同的习语:

Connection conn = null;
try {
  conn = ...
  // do stuff
} finally {
  try { conn.close(); } catch (Exception e) { }
}

You could point out at this point that this isn't object destruction and that you could, for example, pass that object to something else and still have a reference to it. You are right on both counts. It is simply as close as Java (and most managed platforms) get.

在这一点上,您可以指出这不是对象销毁,例如,您可以将该对象传递给其他对象,并且仍然拥有对它的引用。你在这两个方面都是对的。它与 Java(和大多数托管平台)一样接近。

But no Java does not, as you say, have a destructor mechanism as in C++. Some people mistake finalizers for this. They are notdestructors and it is dangerous to use them as such.

但是,正如您所说,没有 Java 没有 C++ 中的析构函数机制。有些人因此误认为终结器。它们不是析构函数,因此使用它们是危险的。

Memory management for a programmer is hard. You can easily leak memory, particularly when doing multithreaded programming (also hard). Experience has shown that the cost of GC, while real and sometimes substantial, is well and truly justified in productivity increases and bug incidences in the vast majority of cases, which is why the vast majority of platforms now are "managed" (meaning they use garbage collection).

程序员的内存管理很难。您很容易泄漏内存,尤其是在进行多线程编程(也很难)时。经验表明,GC 的成本虽然是真实的,有时是巨大的,但在绝大多数情况下,在生产力提高和错误发生率方面是完全合理的,这就是为什么现在绝大多数平台都被“管理”(意味着他们使用垃圾收集)。