news 2026/5/1 4:42:10

JVM-finalize()方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JVM-finalize()方法

Finalize方法不被推荐使用原因

该函数允许在子类中被重写,用于在对象被回收时进行资源地释放。目前,普遍的认识是,尽量不要使用finalize()函数进行资源释放,原因主要有以下几点:

1、在finalize()时可能会导致对象复活;

2、finalize()函数的执行时间是没有保障的,它完全由GC线程决定,极端情况下,若不发生GC,则finalize()将没有机会执行;

3、一个糟糕的 finalize()会严重影响GC的性能;

函数finalize()是由FinalizerThread 线程处理的。正式回收对象前,这类对象会被封装为Finalizer引用对象(本质是引用类型),并被加入ReferenceQueue引用队列(内部是链表结构),由该队列调度FinalizerThread执行其finalize()方法。

Finalizer内部封装了实际的回收对象,如图所示。可以看到next、prev 为实现链表所需

,它们分别指向队列中的下一个元素和上一个元素。

finalizee是要回收的对象,比如,在后续的示例中就为LongFinalize$LF。

由于对象在回收前被Finalizer 的referent 字段进行“强引用”,并加入了FinalizerThread的执行队列,这意味着对象又变为可达对象,因此阻止了对象的正常回收。由于在引用队列中的元素排队执行finalize()方法,一旦出现性能问题,将导致这些垃圾对象长时间堆积在内存中,可能会导致OOM异常。

-Xmx10m -Xms10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="D:/f.dump"

使用上述参数进行堆内存溢出的dump文件下载,并使用Mat进行文件分析:

从最大对象中可以看到,目前系统中有大量的Finalizer类,这意味着FinalizerThread 执行

列可能一直持有对象而来不及执行,因此大量的对象堆积而无法被释放,最终导致了这个OOM。

去掉LF类的finalize()方法,再次以相同的参数运行这段程序。可以观察到,程序很快正常结束。由此,|可以进一步说明finalize()对GC产生的影响。

注意:一个糟糕的finalize()可能会使对象长时间被Finalizer 引用,而得不到释放,因

此这会进一步增加GC的压力。因此,finalize()应该是尽量少 地被使用。

Finalizer方法重写导致OOM原因

@Override protected void finalize() { try { System.out.println(Thread.currentThread().getId()); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } }

核心逻辑finalize()会让对象的 “回收流程变复杂 + 延迟”。

finalize()Object类的一个方法,原本设计是让对象在被垃圾回收前做最后一次资源清理,但它的执行机制会改变对象的 “可回收状态”。

重写与不重写的区别

当你不重写finalize()时:

1、循环里创建的LF对象是普通强引用对象,循环结束后,这些对象没有任何引用(f是局部变量,每次循环后就失效了)。

2、GC 可以直接识别这些 “无引用的对象”,将其回收,内存会被循环利用,所以不会触发 OOM。

重写finalize()的情况:对象被 “延迟回收”,最终堆积导致 OOM:

当你重写finalize()后,JVM 会给这类对象加一层 “特殊处理”:

1、包装为 Finalizer 引用

每个LF对象创建后,JVM 会把它包装成java.lang.ref.Finalizer对象Finalizer是一种特殊的引用类型,属于 JVM 内部维护的引用)

2、对象暂时 “变可达”

Finalizer对象会被加入 JVM 的Finalizer队列(一个链表结构),此时LF对象因为被Finalizer引用,会从“无引用状态”变成“可达状态”——GC 认为它还有引用,不能立即回收

3、FinalizerThread 处理缓慢,对象堆积

JVM 会启动一个低优先级线程FinalizerThread,负责遍历Finalizer队列、执行每个Finalizer对应的finalize()方法。

但你在finalize()里加了Thread.sleep(1000),导致FinalizerThread处理每个对象要等 1 秒 —— 而你循环每秒能创建大量LF对象,处理速度远赶不上创建速度

最终结果:大量LF对象被Finalizer持有、无法回收,内存被占满,触发 OOM。

finalize()到底是干啥的?为什么“过时”了

它原本的设计是 “让对象在回收前做资源清理”,但因为:

1、执行依赖低优先级的FinalizerThread,可能迟迟不执行;

2、会延迟对象回收,甚至会导致 OOM;

3、执行结果不可控;

所以finalize()已经被 JDK 标记为过时方法(@Deprecated),现在完全不推荐使用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 22:39:44

SAP BTP 云到本地数据访问怎么选接口才不踩坑:RFC、OData v2/v4 与 Plain HTTP 的性能对比与落地策略

在很多企业里,SAP S/4HANA 或 ECC 仍然承担着核心交易与主数据的落地,SAP BTP 上的 ABAP Environment 则更像一个面向创新的扩展层:做新的应用、做跨系统编排、做云上 API 聚合。问题也就随之出现了:当 ABAP Environment 需要读取 On-Premise 数据时,接口技术选型到底会把…

作者头像 李华
网站建设 2026/4/25 5:15:09

多语言AI落地难点突破:HY-MT1.5格式化翻译实战案例

多语言AI落地难点突破:HY-MT1.5格式化翻译实战案例 在多语言全球化加速的背景下,高质量、低延迟的机器翻译成为智能应用的核心需求。然而,传统翻译模型在面对混合语言输入、复杂文本格式保留(如HTML标签、代码块)以及…

作者头像 李华
网站建设 2026/4/30 19:27:59

Hunyuan翻译模型支持批量处理?自动化脚本实战示例

Hunyuan翻译模型支持批量处理?自动化脚本实战示例 混元(Hunyuan)是腾讯推出的系列大模型之一,其最新发布的 HY-MT1.5 翻译模型在多语言互译、边缘部署和功能扩展方面表现出色。该系列包含两个核心模型:HY-MT1.5-1.8B …

作者头像 李华
网站建设 2026/4/23 18:39:21

Hunyuan-HY-MT1.5镜像使用手册:网页推理功能快速启用指南

Hunyuan-HY-MT1.5镜像使用手册:网页推理功能快速启用指南 1. 引言 随着全球化进程的加速,高质量、低延迟的翻译服务成为跨语言交流的核心需求。腾讯推出的Hunyuan-HY-MT1.5系列翻译大模型,凭借其卓越的语言理解能力和多场景适配性&#xff0…

作者头像 李华
网站建设 2026/4/23 11:18:13

HY-MT1.5与NLLB对比评测:低资源语言翻译部署表现

HY-MT1.5与NLLB对比评测:低资源语言翻译部署表现 在多语言交流日益频繁的今天,高质量、低延迟的机器翻译模型成为跨语言沟通的核心基础设施。特别是在低资源语言场景下,如何在有限算力条件下实现高精度翻译,是工业界和学术界共同…

作者头像 李华
网站建设 2026/4/27 10:44:53

HY-MT1.5-7B训练数据揭秘:WMT25夺冠背后的技术逻辑

HY-MT1.5-7B训练数据揭秘:WMT25夺冠背后的技术逻辑 1. 引言:从WMT25冠军到开源落地的技术跃迁 在2025年国际机器翻译大会(WMT25)的评测中,腾讯混元团队凭借其翻译系统斩获多项语言对的第一名,成为当年最受…

作者头像 李华