千家信息网

使用finalize方法对垃圾回收有哪些影响

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,今天就跟大家聊聊有关使用finalize方法对垃圾回收有哪些影响,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。java提供了一个finaliz
千家信息网最后更新 2026年11月02日使用finalize方法对垃圾回收有哪些影响

今天就跟大家聊聊有关使用finalize方法对垃圾回收有哪些影响,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。


java提供了一个finalize方法,可以帮助我们进行资源释放,类似于C++中的析构函数。但是目前普遍的认识是不要使用,为什么呢?就是因为对java虚拟机的垃圾回收有影响。

一、为什么有影响

我们都知道一个对象如果没有了任何引用,java虚拟机就认为这个对象没什么用了,就会对其进行垃圾回收,但是如果这个对象包含了finalize函数,性质就不一样了。怎么不一样了呢?

java虚拟机在进行垃圾回收的时候,一看到这个对象类含有finalize函数,就把这个函数交给FinalizerThread处理,而包含了这个finalize的对象就会被添加到FinalizerThread的执行队列,并使用一个链表,把这些包含了finalize的对象串起来。

他的影响在于只要finalize没有执行,那么这些对象就会一直存在堆区,不过这里只是4个包含了finalize的对象,影响不是那么大,如果有一万个或者是十万个呢?这就影响大了。

finalize的原理其实很简单,在这里简要的梳理一下:

(1)对象在初始化的过程中会判断是否重写了finalize,方法是判断两个字段标志has_finalizer_flag和RegisterFinalizersAtInit。

(2)如果重写了finalize,那就把当前对象注册到FinalizerThread的ReferenceQueue队列中。注册之后的对象就叫做Finalizer。方法是调用register_finalizer函数。此时java虚拟机一看当前有这个对象的引用,于是就不进行垃圾回收了。

(3)对象开始被调用,FinalizerThread线程负责从ReferenceQueue队列中获取Finalizer对象。开始执行finalize方法,在执行之前,这个对象一直在堆中。

(4)对象执行完毕之后,将这个Finalizer对象从队列中移除,java虚拟机一看对象没有引用了,就进行垃圾回收了。

这就是整个过程。不过在这里我们主要看的是finalize方法对垃圾回收的影响,其实就是在第三步,也就是这个对象含有finalize,进入了队列但一直没有被调用的这段时间,会一直占用内存。

我们使用一个案例来分析一波:

二、案例演示

我们创建一个类

 1public class TestFinalizer {
2 public static class Fdd {
3 //分配1M
4 private byte[] content = new byte[1024*1024];
5 @Override
6 protected void finalize() {
7 System.out.println("finalize被执行");
8 }
9 }
10 public static void main(String[] args) {
11 for (int i = 0; i < 1000; i++) {
12 Fdd fdd = new Fdd();
13 }
14 }
15}

现在创建了类,我们设置一下参数。

1# 最大堆内存
2-Xmx5m
3# 最小堆内存
4-Xms5m
5# 堆内存溢出错误打印
6-XX:+HeapDumpOnOutOfMemoryError
7# 把堆相关信息保存在下列路径
8-XX:HeapDumpPath=F:/a.dump

在main方法中,创建了1000个Fdd对象,如果不执行finalize方法,那么因为没有调用所以会进行垃圾回收,此时不断我们创建多少个,都不会出现任何问题。但是如果存在finalize方法,就不一样了。

 1java.lang.OutOfMemoryError: Java heap space
2Dumping heap to F:/a.dump ...
3finalize被执行
4finalize被执行
5finalize被执行
6finalize被执行
7finalize被执行
8finalize被执行
9finalize被执行
10Unable to create F:/a.dump: File exists
11Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
12 at com.fdd.chapter2.TestFinalizer$Fdd.(TestFinalizer.java:6)
13 at com.fdd.chapter2.TestFinalizer.main(TestFinalizer.java:14)

我们看到每个对象都会执行finalize,在执行之前的这段时间一直会在堆区,执行完了就会被清理,所以你看到这里执行了不少于5次的finalize方法。但是对象一旦超出了我们设置的5M,就会出现内存溢出。一句话总结就是出现了对象堆积。现在使用MAT工具来分析一下。

Mat工具是一个插件,也可以自己下载一个。下载完成之后打开我们刚刚生成的a.dump即可。

下面这张图就是分析的结果:

a这块的内容就是Finalizer,也就是我们的Fdd对象,b包含的比较多,乱七八糟的剩余信息。当然你也可以查看一些其他的信息。都在MAT工具上。还有一些正在执行的finalizer和准备执行的。

看完上述内容,你们对使用finalize方法对垃圾回收有哪些影响有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

对象 方法 垃圾 影响 就是 内存 函数 队列 内容 信息 工具 分析 也就是 时间 案例 过程 最小 乱七八糟 没什么 一句话 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网金融科技 深圳市人人互联网科技有限公司 互联网佳科技有限公司 北京路客互联网科技有限公司 互联网的科技 互联网金融监管科技数据 中国互联网科技股 北京互联网科技公司 世界互联网领先科技成果 远拓互联网科技 腾讯科技 互联网女皇 新浪科技互联网 互联网科技公司需要的职位 现代科技和互联网有关系吗 银川新华互联网科技学校联系电话 想开互联网科技公司怎么样 滨湖区互联网智能科技产品有哪些 互联网科技快讯热点 湖北辰鑫科技互联网 互联网企业和网络科技有限公司 互联网科技有限公司经营范围 美国互联网科技巨头监管 中国 科技 互联网 融势互联网科技 互联网科技博客 互联网科技人工智能实验室 佛山市翊博互联网络科技有限公司 特约风豹互联网科技为什么扣费 卡尔迅互联网科技有限公司 世界互联网科技成果奖
0