栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

你完全错了。

简短答案:这

finalize()
是一种在对象准备好进行垃圾回收之前(当没有对象对其进行强烈引用时)清理资源(例如打开的文件)的方法。它可能/不被调用。这是内存释放之前的第一步。

长答案:

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

  1. 创建对象时,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(),它将关闭必需的资源或用于最终日志等。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/506448.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号