java 重写 Object 类的 finalize() 方法有什么用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5635749/
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
What is the use of overriding the finalize() method of Object class?
提问by Rahul
As far as I know , in java if we want to manually call the garbage collector we can do System.gc().
1.What are the operations that we do inside our overriden finalize() method?
2.Is it required to override the finalize() method if we want to manually call the JVM garbage collector?
据我所知,在java中如果我们想手动调用垃圾收集器,我们可以做System.gc()。
1.我们在覆盖的 finalize() 方法中做了哪些操作?
2.手动调用JVM垃圾回收器是否需要覆盖finalize()方法?
回答by Tadeusz Kopec
What are the operations that we do inside our overriden finalize() method?
我们在重写的 finalize() 方法中做了哪些操作?
Free memory alocated manually (through some native calls) i.e. not managed by GC. It is a really rare situation.
Some people put there also a check, that other resources connected with the object have already been released - but it's only for debugging purposes and it's not very reliable.
You must remember that:
可用内存手动分配(通过一些本机调用),即不由 GC 管理。这是一种非常罕见的情况。有些人还检查了与该对象相关的其他资源是否已经被释放——但这仅用于调试目的,并不是很可靠。
你必须记住:
finalize
is about memory and only memory.- You have no control when it will be invoked and even whetherit be invoked.
finalize
是关于记忆的,而且只是记忆。- 您无法控制何时调用它,甚至无法控制它是否被调用。
So never everput there releasing any other resources (like file handles, locks). All those resources must be released manually.
And overriding finalize has nothing to do with calling System.gc()
.
所以永远不要在那里释放任何其他资源(如文件句柄、锁)。所有这些资源都必须手动释放。
覆盖 finalize 与调用System.gc()
.
回答by Puce
Others already explained the finalize method.
其他人已经解释了 finalize 方法。
Note however, that best practices is to design a "close"/ "clean-up"/ "termination" method to close/ clean-up the object and ask the developer to call this method explicitly. Finalizers should only be used as a safety net. (See "Item 7: Avoid finalizers" of "Effective Java" by Joshua Bloch)
但是请注意,最佳实践是设计一个“关闭”/“清理”/“终止”方法来关闭/清理对象并要求开发人员显式调用此方法。终结器只能用作安全网。(参见 Joshua Bloch 的“Effective Java”的“Item 7:Avoid finalizers”)
Update:
更新:
In this case also consider to implement AutoCloseableto support try-with-resources blocks.
在这种情况下,还要考虑实现AutoCloseable以支持 try-with-resources 块。
回答by McGlone
Overriding the finalize method is often done if you need to manually release resources (particularly those that would use large amounts of memory or cause locks, if they weren't released). For example, if you have an object that has a lock on a file or database table, you may want to override your finalize method in order to release those objects for use when your object is garbage collected.
如果您需要手动释放资源(特别是那些会使用大量内存或导致锁定的资源,如果它们没有被释放),通常会覆盖 finalize 方法。例如,如果您有一个锁定文件或数据库表的对象,您可能需要覆盖您的 finalize 方法,以便在您的对象被垃圾收集时释放这些对象以供使用。
As for whether or not overriding finalize is required, it absolutely is not. You can call System.gc() without ever overriding a finalize method. One word of caution, though - calling System.gc() doesn't absolutely dictate that the garbage collector will do anything. Consider it more of a "recommendation" to the JVM to run garbage collection, as opposed to a "mandate".
至于是否需要覆盖 finalize,绝对不需要。您可以调用 System.gc() 而无需覆盖 finalize 方法。但是,请注意一个词 - 调用 System.gc() 并不能绝对决定垃圾收集器会做任何事情。将其视为对 JVM 运行垃圾收集的“推荐”,而不是“强制”。
回答by Andreas Dolk
For very rare cases it may be useful or necessary to implement finalize
for freeing allocated resources. This method is always called when an instance is destroyed finally.
对于非常罕见的情况,实现finalize
释放分配的资源可能是有用的或必要的。这个方法总是在实例最终被销毁时调用。
May be helpful if you work with native code and need to free allocated resources in the native code area.
如果您使用本机代码并需要释放本机代码区域中分配的资源,可能会有所帮助。
But use it with care, because implementing finally
will slow down the garbage collector dramatically and kill performance.
但是要小心使用它,因为实施finally
会显着减慢垃圾收集器的速度并降低性能。
回答by toomasr
1) Any clean up that you want to do on object destruction (if you keep some handles open and nobody has called an explicit close for example). Keep in mind that you don't know when this will happen because the JVM will call the GC and not you.
1) 您想在对象销毁时进行的任何清理(例如,如果您保持某些句柄打开并且没有人调用显式关闭)。请记住,您不知道何时会发生这种情况,因为 JVM 将调用 GC 而不是您。
2) Nope.
2)不。
Side note, you should not manually call the Garbage Collector, see the answer here, Why do you not explicitly call finalize() or start the garbage collector?
旁注,您不应该手动调用垃圾收集器,请参阅此处的答案,为什么不显式调用 finalize() 或启动垃圾收集器?
回答by Robby Pond
There is no guarantee that the finalizer will be called promptly so you should not do anything critical in your finalize method.
无法保证会立即调用终结器,因此您不应在终结方法中执行任何关键操作。
- Release system resources (Such as IOStreams) as a safety net if they weren't already closed or released.
- Release system resources iin native code that the GC doesn't know about.
- 如果系统资源(例如 IOStreams)尚未关闭或释放,则将它们释放为安全网。
- 在 GC 不知道的本机代码中释放系统资源。
回答by Ajoy Bhatia
@Andreas_D: I agree with what reef says and what he implies is that, if finalize() contains code that makes the current instance ineligible for GC, i.e. brings it back to life by giving a live thread a reference to this instance, then the next time that that instance becomes eligible for GC, DO NOT expect finalize() to be called by the JVM again. As far as the JVM is concerned, it has done its duty by calling finalize() once and cannot be bothered to do it again and again just because you keep bringing the instance back to life again. If it did, then that object would never be GC'ed. (Of course, you might want the instance never to be GC'ed. Then just have a live thread maintain a reference to it. If no live thread has a reference to the instance, the instance is as good as dead, anyway.)
@Andreas_D:我同意 Reef 所说的以及他暗示的意思是,如果 finalize() 包含使当前实例不符合 GC 条件的代码,即通过为活动线程提供对此实例的引用来使其恢复生机,那么下次该实例符合 GC 条件时,不要期望 JVM 再次调用 finalize()。就 JVM 而言,它通过一次调用 finalize() 完成了它的职责,并且不会因为您不断使实例再次恢复而烦恼一次又一次地执行它。如果是这样,那么该对象将永远不会被 GC 处理。(当然,您可能希望实例永远不会被 GC 处理。然后让一个活动线程维护对它的引用。如果没有活动线程引用该实例,那么无论如何,该实例就如同死了一样。)
回答by Robin Green
1.What are the operations that we do inside our overriden finalize() method?
1.我们在覆盖的 finalize() 方法中做了哪些操作?
Cleaning up resources that cannot be handled by garbage collection.
清理垃圾收集无法处理的资源。
2.Is it required to override the finalize() method if we want to manually call the JVM garbage collector?
2.手动调用JVM垃圾回收器是否需要覆盖finalize()方法?
No, these two things are unrelated.
不,这两件事无关。
finalize should certainly not call the garbage collector itself. In fact, finalize is called bythe garbage collector (but is not guaranteed to be called at all).
finalize 当然不应该调用垃圾收集器本身。事实上,finalize 是由垃圾收集器调用的(但根本不保证会被调用)。