您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

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

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

你完全错了。

简短答案:这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()时就被终止了。

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

其他 2022/1/1 18:28:33 有666人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶