本文介绍了当我们在其上显式调用finalize()时,是否释放了对象内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就我的理解最终确定()和GC是两个不同的方面。 GC使用finalize()方法释放对象内存。我们不能说明GC何时会发生(即使我们明确地调用了System.gc())。但是我们可以在一个Object上明确地调用finalize()。

 函数会立即执行(内存释放)还是等待GC 
像System.gc()调用一样发生?

同样根据文档,finalize方法永远不会由Java虚拟机多次调用给出的对象。



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

 如果在显式调用object.finalize()时没有释放对象内存,那么将不会被
调用再次在GC过程中违反只调用一次规则?


解决方案

你完全错了。

简短回答:
finalize()是一种清理资源的方法(如打开的文件)就在对象准备好垃圾收集之前(当没有对象强引用它时)。它可能不会被调用。这是一个超前的内存释放。



长答案:

有一个单独的守护进程线程称为finalizer线程负责调用finalize()方法。定位队列是准备好调用finalize()方法的对象的队列。


  1. 创建对象时,JVM会检查如果用户已经重写了finalize()方法。如果它有,那么它在内部注意到这个特定的对象有finalize()方法。

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


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



    2b)它已经存在,然后它被添加到最终化队列中。它从表(1)中删除对象的入口。




终结者线程继续轮询队列。对于队列中的每个对象,都会调用它的finalize()方法。从(2)中调用finalize()循环后再次重复。如果这个对象仍然没有强大的参考,然后发送给GC。如果
它已经然后ALWAYS(2a)被调用,因为该条目在(2b)中被删除

 基本上finalize )方法只被调用一次。 

那么上述周期的问题是什么?

您不知道何时调用finalize(),因为您无法控制何时调用GC。有时可能发生的是,您正在finalize()中打印值,但输出从不显示,因为您的程序可能在调用finalize()时终止。




As far as my understanding goes finalize() and GC are two different aspects. GC uses finalize() method to free Object memory. We cannot state when GC will occur(even if we explicitly call System.gc()). But we can explicitly call finalize() on an Object.

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

Also as per the docs the finalize method is never invoked more than once by a Java virtual machine for any given object.

So what happens when we call finalize() first and GC happens at a later point of time.

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? 
解决方案

You have got it completely wrong.

Short answer: finalize() is a means to clean up resources (such as open files) just before the object is ready for garbage collection ( when no object has strong reference to it). It might/not be called. It is one step ahead of memory deallocation.

Long answer:

There is a separate daemon thread called as finalizer thread which is responsible for calling finalize() method . Finalization queue is the queue where objects which are ready to be called finalize() method are placed.

  1. When an Object is created, JVM checks if the user has overridden the finalize() method. If it has then it internally notes that this particular object has finalize() method.

When an object is ready for garbage collection, then the garbage collector thread checks if this particular object has finalize() from table mentioned in (1).

  • 2a) If it doesn’t then it is sent for garbage collection.

    2b) It is has, then it is added to the finalization queue. And it removes the entry of the object from the table (1).

Finalizer thread keeps polling the queue. For every object in the queue, its finalize() method is called. After calling the finalize() cycle from (2) is again repeated. If this object still has no strong reference, then sent for GC. If it has then ALWAYS (2a) is called because the entry was deleted in (2b)

Basically finalize() method is only called once.

So what’s the issue with the above cycle?

You do not know when finalize() is called as you have no control over when GC is called. Sometimes it might happen that you are printing the value’s in finalize() but the output is never shown, because your program might have got terminated by the time finalize() is called.

Hence avoid using it. Instead create a method say dispose() which will close the necessory resources or for final log etc.

这篇关于当我们在其上显式调用finalize()时,是否释放了对象内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 01:47