你完全错了。
简短答案:这finalize()
是一种在对象准备好进行垃圾回收之前(当没有对象对其进行强烈引用时)清理资源(例如打开的文件)的方法。它可能/不被调用。这是内存释放之前的第一步。
长答案:
有一个单独的守护程序线程称为finalizer线程,它负责调用finalize()方法。终结队列是放置准备好要调用finalize()方法的对象的队列。
当对象准备好进行垃圾回收时,垃圾回收器线程会检查该特定对象是否具有(1)中提到的表中的finalize()。
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()时就被终止了。