finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?

垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的 finalize() 方法 但是在 Java 中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说 filalize() 可能永远不被执行,显然指望它做收尾工作是靠不住的。 那么finalize() 究竟是做什么的呢? 它最主要的用途是回收特殊渠道申请的内存。Java 程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种 JNI(Java Native Interface)调用non-Java 程序(C 或 C++), finalize() 的工作就是回收这部分的内存。

finalize() 方法

Java 可以使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做一些必要的清理工作。

finalize()方法什么时候被调用?

这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。

析构函数(finalization) 的目的是什么?

析构函数的目的是:在清除对象前,完成一些清理工作,比如:释放内存等。

final 和 finalize 的区别?

final关键字可以用于类、方法、变量前,用来表示该类、方法、变量具有不可变的特性。 finalize方法用于回收资源,可以为任何一个类添加finalize方法。该方法将在垃圾回收器清除对象之前调用。

与toString方法类似,finalize方法也是Java中所有类中必有的方法,因为它是属于Object根类的方法,默认情况下,Java中所有的类都是Object类的子类。

finalize方法会被自动调用调用的时机 为:在销毁(回收)该对象前,finalize方法会被自动调用

以上这句话听起来的确很抽象,什么是销毁(回收)对象呢?所谓的销毁对象就是把该对象所占用的堆内存空间给释放掉,也就是释放出更多的内存资源,释放出来的内存空间可以供别的对象使用, 这一点是非常重要的**。**

搞清楚这个问题之后,我们就要思考,什么时候会销毁对象呢?**当垃圾回收器确定不存在该对象的更多引用时,由垃圾回收器自动调用该方法。**我画一个图解释一下,比如说我现在有一个Dog对象,它在堆内存中占了一片空间,此时d是这个对象的引用。如下图所示

当我调用完Dog对象的eat方法之后,以后就再也不使用这个Dog对象了,可以将d赋值为null,那么原来那个Dog对象就没有被引用了,将来也不会再用到。此时,垃圾回收器会自动回收或者说销毁该对象,那是不是一把d赋值为null,就马上销毁该对象呢?不是的,垃圾回收器到底什么时候回收该对象,有它自己的规则,并不是说该对象没被引用了,马上回收该对象,我们也可以来进行验证一下,根据上文的描述,我们知道,当该对象被回收时,会先去调用finallize方法,默认情况下,子类的finalize方法是继承自Object父类,先来看看Object父类中的finalize方法是如何编写的,如下图所示:

根据观察可以发现,Object类的finalize方法中没有任何的代码。为了方便观察到效果,我们在Dog类中重写父类Object的finalize方法,如下图所示:

重写完之后,我们运行程序,来验证finalize方法在此时是否会被自动调用,此时main方法中的代码是这样的,在第7行,已经将d赋值为null,意味着Dog对象已经没有任何引用了。

运行程序,结果如下所示:观察发现,明明Dog对象已经没有被引用了,为什么finalize没有被调用呢?如我刚刚所说,虽然Dog对象没有被引用,但是垃圾回收器并不会马上回收Dog对象,它有自己的回收时机,现在只能确定该Dog对象已经可以被回收了,但是还没被回收,所以finalize方法没有被调用。

为了看到显示的效果,我们可以编写代码,手动调用垃圾回收器让它回收该Dog对象,在main方法中,我们添加上这样一句代码,调用垃圾回收器:

再次运行程序,观察结果:发现finalize方法果然被自动调用了,但是你再仔细观察代码发现,代码的输出是先执行第9行,然后再去调用finalize方法,也就是说System.gc调用之后,并不会阻塞在那里,等调用完finalize方法之后再执行第9行,而是一调用垃圾回收器就继续运行代码了,就先输出了第9行的代码,finalize方法反而在其后,这是允许的

在实际的编程开发中,finalize方法一般是用来释放资源 (比如数据库的连接对象文件流的对象 等这些都叫资源)的,且作为程序员,我们很少在子类中去重写这个方法

相关推荐
语戚8 分钟前
力扣 968. 监控二叉树 —— 贪心 & 树形 DP 双解法递归 + 非递归全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·
quxuexi30 分钟前
网络通信安全与可靠传输:从加密到认证,从状态码到可靠传输
java·安全·web
hrhcode1 小时前
【java工程师快速上手go】二.Go进阶特性
java·golang·go
小碗羊肉3 小时前
【从零开始学Java | 第三十一篇下】Stream流
java·开发语言
❀͜͡傀儡师3 小时前
Spring AI Alibaba vs. AgentScope:两个阿里AI框架,如何选择?
java·人工智能·spring
aq55356003 小时前
Laravel10.x重磅升级,新特性一览
android·java·开发语言
一 乐4 小时前
酒店预订|基于springboot + vue酒店预订系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·酒店预订系统
Moe4884 小时前
Spring AI Advisors:从链式增强到递归顾问
java·后端
敖正炀4 小时前
ReentrantReadWriteLock、ReentrantLock、synchronized 对比
java
cike_y4 小时前
Java反序列化漏洞-Shiro721流程分析
java·反序列化·shiro框架