系统相关
首页 > 系统相关> > 当我们显式调用finalize()时,是否释放了对象内存?

当我们显式调用finalize()时,是否释放了对象内存?

作者:互联网

这个问题已经在这里有了答案:            >            Java and manually executing finalize                                    3个
>            When is the finalize() method called in Java?                                    16个
就我的理解而言,finalize()和GC是两个不同的方面. GC使用finalize()方法释放对象内存.我们无法声明何时发生GC(即使我们显式调用System.gc()).但是我们可以在对象上显式调用finalize().

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

此外,根据docs,对于任何给定对象,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()是在对象准备好进行垃圾回收之前(当没有对象对其有强引用时)清理资源(例如打开的文件)的方法.它可能/不被调用.这是内存释放之前的第一步.

长答案:

有一个单独的守护程序线程称为finalizer线程,它负责调用finalize()方法.终结队列是放置准备好要调用finalize()方法的对象的队列.

>创建对象后,JVM会检查用户是否覆盖了finalize()方法.如果具有,则在内部指出该特定对象具有finalize()方法.

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

> 2a)如果不是,则将其发送到垃圾回收.

2b)有,然后将其添加到完成队列.并且它从表(1)中删除对象的条目.

终结器线程不断轮询队列.对于队列中的每个对象,将调用其finalize()方法.调用finalize()循环后,再次重复从(2)开始的循环.如果该对象仍然没有强引用,则发送给GC.如果
    它具有ALWAYS(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(),它将关闭必需的资源或用于最终日志等.

标签:finalizer,java,garbage-collection,jvm
来源: https://codeday.me/bug/20191012/1899588.html