java - 当我们显式调用 Finalize() 时,对象内存是否被释放?

标签 java garbage-collection jvm finalizer

据我了解,finalize() 和 GC 是两个不同的方面。 GC使用finalize()方法来释放Object内存。我们无法说明 GC 何时发生(即使我们显式调用 System.gc())。但我们可以在对象上显式调用 Finalize()。

Will the function be executed immediately(memory freed) or it waits till GC
occurs like System.gc() call?

此外,根据文档,Java 虚拟机对于任何给定对象都不会多次调用 Finalize 方法。

那么当我们首先调用 Finalize() 并在稍后的时间点发生 GC 时会发生什么。

If object memory is not freed on explicit call to object.finalize() then would't 
it being called again in the GC process violate the calling only once rule? 

最佳答案

你完全错了。

简短回答: Finalize() 是一种在对象准备好进行垃圾回收之前(当没有对象对其具有强引用时)清理资源(例如打开的文件)的方法。它可能/不会被调用。它比内存释放提前了一步。

长答案:

有一个单独的守护线程,称为终结器线程,负责调用 Finalize() 方法。 Finalization队列是放置准备好调用finalize()方法的对象的队列。

  1. 创建对象时,JVM 会检查用户是否重写了 Finalize() 方法。如果有,那么它会在内部注意到该特定对象具有 Finalize() 方法。

当一个对象准备好进行垃圾收集时,垃圾收集器线程会检查该特定对象是否具有 (1) 中提到的表中的 Finalize()。

  • 2a) 如果没有,则将其发送至垃圾回收。

    2b) 是,然后将其添加到终结队列中。并且它从表 (1) 中删除该对象的条目。

终结器线程不断轮询队列。对于队列中的每个对象,都会调用其 Finalize() 方法。调用 Finalize() 后,再次重复 (2) 中的循环。如果这个对象仍然没有强引用,则送去GC。如果 然后总是调用 (2a),因为该条目已在 (2b) 中删除

Basically finalize() method is only called once.

那么上述循环有什么问题呢?

From (1). Its take extra time in object creation. Memory allocation in Java is 5x to 10x faster than malloc/calloc etc. All the time gained is lost in the procedure of noting the object in the table etc. I once tried it. Create 100000 objects in a loop and measure the time taken for program to terminate in 2 cases: One with no finalize(), Second with finalize(). Found it to be 20% faster.

From (2b): Memory Leakage and Starvation. If the object in the queue has references to a lot of memory resources, then all those objects wont get freed unless this object is ready for GC.If all the objects are heavy weight objects, then there can be a shortage.

From (2b): Because finalize() is called only once, what if in teh finalize() you had a strong reference to “this” object. Next time the object’s finalie() is never called hence can leave the object in an inconsistent state.

If inside finalize() an exception is thrown, it is ignored.

您不知道何时调用 Finalize(),因为您无法控制何时调用 GC。有时可能会发生这样的情况:您在 Finalize() 中打印值,但输出从未显示,因为您的程序可能在调用 Finalize() 时已终止。

因此避免使用它。相反,创建一个方法,例如 dispose() ,它将关闭必要的资源或最终日志等。

关于java - 当我们显式调用 Finalize() 时,对象内存是否被释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18510582/

相关文章:

java - 在 JNI 函数中,当我就地更改从 Java 代码传递的数组时,数组不会修改

jvm - 如何强制 HotSpot JVM 覆盖堆转储文件?

java - Jackson无法解析json,返回NPE

java - Observer 和 Observable 没有通知

android - ListView 性能很慢

Java、JIT 和垃圾收集器效率

java - 用于执行一组算法的 JVM 指令

java - 如何使用java上的move方法将文件从Alfresco Server的一个绝对路径移动到另一个目标路径

java - 如何使用 Watson Discovery API 批量上传文档?

python - pythonapi.PyObject_GC_UnTrack 返回什么?