你完全错了。
简短答案:这
finalize()是一种在对象准备好进行垃圾回收之前(当没有对象对其进行强烈引用时)清理资源(例如打开的文件)的方法。它可能/不被调用。这是内存释放之前的第一步。
长答案:
有一个单独的守护程序线程称为finalizer线程,它负责调用finalize()方法。终结队列是放置准备好要调用finalize()方法的对象的队列。
- 创建对象时,JVM将检查用户是否覆盖了finalize()方法。如果具有,则在内部指出该特定对象具有finalize()方法。
当对象准备好进行垃圾回收时,垃圾回收器线程会检查该特定对象是否具有(1)中提到的表中的finalize()。
- 2a)如果没有,则将其发送以进行垃圾回收。
2b)有,然后将其添加到完成队列。并且它从表(1)中删除对象的条目。
终结器线程不断轮询队列。对于队列中的每个对象,将调用其finalize()方法。在调用finalize()循环之后,再次重复从(2)开始的循环。如果该对象仍然没有强引用,则发送给GC。如果具有,那么将始终调用(2a),因为该条目已在(2b)中删除
Basically finalize() method is only called once.
那么上述周期有什么问题?
从(1)。在对象创建上需要花费额外的时间。Java中的内存分配比malloc /
calloc等快5到10倍。在表等对象的记录过程中,所有获得的时间都浪费了。我曾经尝试过。在一个循环中创建100000个对象,并在2种情况下测量程序终止所需的时间:一种不带有finalize(),第二种不带有finalize()。发现它快了20%。从(2b):内存泄漏和饥饿。如果队列中的对象引用了很多内存资源,那么除非这些对象准备好用于GC,否则所有这些对象都不会被释放;如果所有对象都是重量级对象,则可能会短缺。
从(2b):因为finalize()仅被调用一次,所以如果在finalize()中您强烈引用了“
this”对象。下次永不调用该对象的finalie(),因此可能使该对象处于不一致状态。如果在finalize()内部抛出异常,则将其忽略。
您不知道何时调用finalize(),因为您无法控制何时调用GC。有时可能会在finalize()中打印值,但是却永远不会显示输出,因为您的程序可能在调用finalize()时就被终止了。
因此,请避免使用它。而是创建一个方法,例如dispose(),它将关闭必需的资源或用于最终日志等。



