理解finalize()-析构函数替代者 (zhuantie)

中国传媒大学计算机考研初复试经验贴 中传的计算机专业考研的话主要分为两大学院:计网学院和国重,大部分专业在计网学院。 阅读详情
理解finalize()-析构函数替代者 在许多方面,Java 类似于 C++。Java 的语法非常类似于 C++,Java 有类、方法和数据成员;Java 的类有构造函数; Java 有异常处理。 但是,如果你使用过 C++ 会发现 Java 也丢掉一些可能是你熟悉的特性。这些特性之一就是析构函数。取代使用析构函数,Java 支持finalize() 方法。 在本文中,我们将描述 finalize() 与 C++ 析构函数的区别。另外,我们将创建一个简单的 Applet 来演示 finalize() 是如何工作的。 最终的界限 与 Java 不同,C++ 支持局部对象(基于栈)和全局对象(基于堆)。因为这一双重支持,C++ 也提供了自动构造和析构,这导致了对构造函数和析构函数的调用,(对于堆对象)就是内存的分配和释放。 在 Java 中,所有对象都驻留在堆内存,因此局部对象就不存在。结果,Java 的设计者觉得不需要析构函数(象 C++ 中所实现的)。 取而代之,Java 定义了一个特殊的方法叫做finalize() ,它提供了 C++ 析构函数的一些功能。但是,finalize() 并不完全与 C++ 的析构函数一样,并可以假设它会导致一系列的问题。finalize() 方法作用的一个关键元素是 Java 的垃圾回收器。 垃圾回收器 在 C/C++、Pascal和其他几种多种用途的编程语言中,开发者有责任在内存管理上发挥积极的作用。例如,如果你为一个对象或数据结构分配了内存,那么当你不再使用它时必须释放掉该内存。 在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当你停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。 当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存。(事实上,你可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。) 在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize()。如果在 Applet 或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize()。 其次,除非垃圾回收器认为你的 Applet 或应用程序需要额外的内存,否则它不会试图释放不再使用的对象的内存。换句话说,这是完全可能的:一个 Applet 给少量的对象分配内存,没有造成严重的内存需求,于是垃圾回收器没有释放这些对象的内存就退出了。 显然,如果你为某个对象定义了finalize() 方法,JVM 可能不会调用它,因为垃圾回收器不曾释放过那些对象的内存。调用System.gc() 也不会起作用,因为它仅仅是给 JVM 一个建议而不是命令。 finalize() 有什么优点呢? 如果finalize() 不是析构函数,JVM 不一定会调用它,你可能会疑惑它是否在任何情况下都有好处。事实上,在 Java 1.0 中它并没有太多的优点。 根据 Java 文档,finalize() 是一个用于释放非 Java 资源的方法。但是,JVM 有很大的可能不调用对象的finalize() 方法,因此很难证明使用该方法释放资源是有效的。 Java 1.1 通过提供一个System.runFinalizersOnExit() 方法部分地解决了这个问题。(不要将这个方法与 Java 1.0 中的System.runFinalizations() 方法相混淆。)不象System.gc() 方法那样,System.runFinalizersOnExit() 方法并不立即试图启动垃圾回收器。而是当应用程序或 Applet 退出时,它调用每个对象的finalize() 方法。 正如你可能猜测的那样,通过调用System.runFinalizersOnExit() 方法强制垃圾回收器清除所有独立对象的内存,当清除代码执行时可能会引起明显的延迟。现在建立一个示例 Applet 来演示 Java 垃圾回收器和finalize() 方法是如何相互作用的。 回收垃圾 通过使用Java Applet Wizard 创建一个新的 Applet 开始。当提示这样做时,输入 final_things 作为 Applet 名,并选择不要生成源文件注释。 接下来,在Java Applet Wizard 进行第三步,不要选择多线程选项。在第五步之前,根据需要修改 Applet 的描述。 当你单击Finish 后,Applet Wizard 将生成一个新的工作空间,并为该项目创建缺省的 Java 文件。从列表 A 中选择适当的代码输入(我们已经突出显示了你需要输入的代码)。 当你完成代码的输入后,配置Internet 浏览器将System.out 的输出信息写到Javalog.txt 文件中。(在IE 选项对话框的高级页面中选择起用 Java Logging。) 编译并运行该 Applet。然后,等待 Applet 运行(你将在状态栏中看到 Applet 已启动的信息),退出浏览器,并打开Javalog.txt 文件。你将会发现类似于下列行的信息: 1000 things constructed 0 things finalized 正如你能够看到的那样,建立了1,000个对象仍然没有迫使垃圾回收器开始回收空间,即使在 Applet 退出时也没有对象被使用。 现在,删除在stop() 方法第一行中的注释符以起用System.gc() 方法。再次编译并运行该 Applet ,等待 Applet 完成运行,并退出浏览器。当你再次打开Javalog.txt 文件,你将看到下列行: 1000 things constructed 963 things finalized 这次,垃圾回收器认为大多数对象未被使用,并将它们回收。按顺序,当垃圾回收器开始释放这些对象的内存时,JVM 调用它们的finalize() 方法。 继承finalize()? 顺便,如果你在类中定义了finalize() ,它将不会自动调用基类中的方法。在我们讨论了finalize() 与 C++ 的析构函数的不同点后,对这个结论不会惊讶,因为为某个类定制的清除代码另一个类不一定会需要。 如果你决定要通过派生一个类的finalize() 方法来调用基类中的finalize() 方法,你可以象其他继承方法一样处理。 protected void finalize() { super.finalize(); // other finalization code... } 除了允许你控制是否执行清除操作外,这个技术还使你可以控制当前类的finalize() 方法何时执行。 结论 然而有益的是,Java 的自动垃圾回收器不会失去平衡。作为便利的代价,你不得不放弃对系统资源释放的控制。不象 C++ 中的析构函数,Java Applet 不会自动执行你的类中的finalize() 方法。事实上,如果你正在使用 Java 1.0,即使你试图强制它调用finalize() 方法,也不能确保将调用它。 因此,你不应当依靠finalize() 来执行你的 Applet 和应用程序的资源清除工作。取而代之,你应当明确的清除那些资源或创建一个try...finally 块(或类似的机制)来实现。 列表 A: final_things.java import java.applet.*; import java.awt.*; class thing { public static int thingcount = 0; public static int thingfinal = 0; public thing() { ++thingcount; } protected void finalize() { ++thingfinal; } } public class final_things extends Applet { public final_things() { } public String getAppletInfo() { return "Name: final_thing/r/n" + "Author: Tim Gooch/r/n" + "Created with Microsoft " + "Visual J++ Version 1.1"; } public void init() { resize(320, 240); } public void destroy() { } public void paint(Graphics g) { g.drawString("Created with Microsoft" + "Visual J++ Version 1.1", 10, 20); } public void start() { while(thing.thingfinal < 1) { new thing(); } } public void stop() { // System.gc(); System.out.println(thing.thingcount + " things constructed"); System.out.println(thing.thingfinal + " things finalized"); } }
Vivado 2018.3实战:用IDELAYE3和ISERDESE3搞定高速ADC数据采集(附仿真源码) 本文详细介绍了在Vivado 2018.3中使用Xilinx UltraScale架构的IDELAYE3和ISERDESE3原语实现高速ADC数据采集的实战方法。通过分析5GHz采样系统的时序挑战,提供从PCB布局到Vivado实现的完整解决方案,包括精密时序校准、多相位数据重组及系统级调试技巧,并附赠仿真源码助力工程师快速掌握高速数据采集技术。 阅读详情

相关推荐

MATLAB锂离子电池伪二维(P2D)模型实现

锂离子电池伪二维(P2D)模型的MATLAB实现。该模型基于Newman等人提出的经典电化学模型,考虑了固液相扩散、电荷守恒和电化学反应动力学。

hie98894的博客 1930

java的finalize方法

我们通常用构造器来创建对象,而Finalize正好相反,构造方法执行对象的初始化操作,finalize方法执行对象的销毁操作. 那我们什么时候需要使用finalize方法呢,我们都知道Java里垃圾回收器可以回收对象使用的内存空间,但是对象可能会 持有很多资源比如Socket、文件句柄等,垃圾收集器无法回收这些资源,因此你需要使用finalize方法帮助GC回收这些 资源,比如关闭打开的文件或者网元资源,删除临时文件等. 一个例子 Object类是所有类的父类,如果你去查看java.lang.Object类

weixin_43831204的博客 1万+

智驾域控制器硬件架构:从接口丛林到算力核心的工程解码

本文深入解析了智驾域控制器硬件架构的设计挑战与工程实践。面对复杂的接口丛林,文章详细探讨了如何高效融合摄像头、雷达等多源传感器数据,并构建以多SOC为核心的强大算力平台。同时,文章强调了电源、时钟、散热等最小系统及车规级可靠性设计的关键作用,为工程师提供了从接口驯服到算力核心协同的完整硬件解码指南。

happy2的博客 482

java中finalize()方法详细介绍

finalize()方法的主要目的是在对象被垃圾回收前进行清理工作。然而,由于其不确定性和潜在的性能问题,finalize()被认为是一个不可靠的资源管理方式。在 Java 中,更推荐使用语句和接口来进行资源管理。对于更复杂的清理需求,可以使用和进行更加精细的控制。随着 Java 9 的引入,finalize()方法被标记为弃用,今后的开发者应尽量避免使用它,并采用更现代化的资源管理技术。

Flying_Fish_roe的博客 3173

2022-2028年中国美容仪行业发展战略规划及投资机会预测报告

报告类型:产业研究 报告格式:电子版、纸介版 出品单位:智研咨询-产业信息网 美容仪是一种根据人体生理机能进行调节改善身体和面部的机器,它按照功能来说有美白、嫩肤、祛斑、祛皱、脱毛、减肥等多种,按照名称来说有超声波导入、光子嫩肤、高周波电疗、RF 电波拉皮、电子祛斑点痣、E 光永久脱毛嫩肤、贾法尼营养导入导出等。 智研咨询发布的《2022-2028年中国美容仪行业发展战略规划及投资机会预测报告》共十七章。首先介绍了中国美容仪行业市场发展环境、美容仪整体运行态势等,接着分析了中...

kt346的博客 468

REALTEK PKE8710ECF开发板入手试玩(一)

REALTEK PKE8710ECF开发板入手试玩

lbqhope的专栏 691

Java中的finalize方法

当一个对象没有引用的时候,对象的垃圾回收器会调用finalize方法。当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作。什么时候被回收:当某个对象没有任何引用时,jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁对象前,会先调用finalize方法。垃圾回收机制的调用,是由系统来决定(有自己的GC算法),也可以通过System.gc()主动触发垃圾回收机制。

SakuraMG的博客 4035

Flutter模块打包AAR集成Android原生项目实践

跨平台开发框架Flutter通过将UI组件渲染为原生代码实现高性能表现,其核心优势在于一套代码可同时运行在iOS和Android平台。在工程实践中,将Flutter模块打包为AAR(Android Archive)进行集成,成为混合开发的主流方案。这种方案既保留了原生项目的稳定性,又能渐进式引入Flutter的高效开发特性。通过配置MethodChannel实现原生与Dart代码通信,开发者可以灵活控制Flutter引擎生命周期,优化内存占用和渲染性能。对于电商、社交等需要快速迭代的业务场景,该方案能显著提

weixin_34025051的博客 399

Java中finalize()方法的使用

finalize()方法,System.gc()方法使用详解

m0_64624615的博客 4197

VTK API 详解(103):vtkGPUVolumeRayCastMapper - GPU加速体绘制

是 VTK 中基于 GPU 的高效体绘制映射器,利用现代显卡的计算能力,通过射线投射算法实现快速且高质量的三维体积渲染。相比 CPU 版本的,GPU 映射器性能大幅提升,支持更复杂的光照和渲染效果,是体绘制的主流选择。是 VTK 中性能优异的GPU体绘制映射器;适合大数据集和实时交互应用;配合灵活设置颜色、透明度和光照;建议在支持OpenGL的环境中使用。

yumeiguo的博客 295

十年芯片资深IC设计工程师面经系列(四)SDC约束

set_driving_cell:当我们的设计是模块级(Block level)的design时,我们的设计前面一般还有其他的设计,那么前面模块的输出便是我们模块的输入,5.1set_false_path:可以单独的时钟或者路径进行约束。set drive :当我们的设计是芯片级(Chip level)的顶层设计时,芯片外围电路要驱动的是负载较大的IO单元,故需要的驱动能力较强,:set_load 是指output端口的负载,设置的值会影响输出到端口的net上的电容,从而影响相应的路径延时。

weixin_47349046的博客 1773

java_finalize浅析

finalize是Java中的一个方法,它是Object类中的一个方法,因此所有的Java类都可以继承它。finalize方法在垃圾回收器回收对象之前被调用,用于释放对象占用的资源。当一个对象不再被引用时,垃圾回收器会在某个时刻自动回收它。在回收之前,垃圾回收器会调用finalize方法,让对象有机会释放它所占用的资源。如果一个对象没有实现finalize方法,或者finalize方法没有正确地释放资源,那么这些资源就会一直被占用,直到程序结束。

qq_52463974的博客 873

【25届数字IC秋招总结】面试经验15——比特大陆-算能

25届数字ic面试记录——比特大陆-算能

lalala0635的博客 554

Java之finalize方法

finalize是回收空间的方法当你的对象没有引用的时候系统是自动调用finalize方法销毁对在堆中的空间 当然你也可以写一些自己的操作,进行finalize的重写finalize也可以用alt+insert快捷键方法 也可以通过自己重写的方法重写的 finalize方法 主动调用 才会输出 实际开发一般不会运用...

y_k_j_c的博客 892

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

什么是Java中的finalize()方法?它有什么作用

finalize()方法是Java中用于在对象被垃圾回收器回收之前执行一些清理工作的方法。尽管它可以用于释放一些非内存资源,但是它并不是一个理想的清理机制,因为它的执行时间和顺序是不可预测的,并且可能会影响垃圾回收器的性能。建议使用其他机制来释放非内存资源,例如try-with-resources语句、finally语句等。如果一个类需要释放非内存资源,建议在类中提供一个显式的方法,让用户手动调用该方法释放资源。

it_xushixiong的博客 5436

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【Java 基础】Java垃圾回收机制 finalize() 方法

finalize() 方法   Java允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做finalize( ),它用来清除回收对象(一些东西,不一定是对象)。 例如,你可以使用finalize()来确保一个对象打开的文件被关闭了。 在finalize()方法里,你可以指定在对象销毁时候(前)要执行的操作。 (就类似Android里面的onDestr

Veyron_wu 1214

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java中的finalize()方法

Java的finalize()方法是Object类的一个protected方法,用于在对象被垃圾回收前执行清理工作。其主要用途包括释放资源(如文件句柄、数据库连接)、重置对象状态和自我清理。但使用时需注意:调用时机不确定(可能永远不会被调用),存在性能开销,异常会被忽略,且存在"对象复活"的可能性。示例代码展示了如何关闭文件资源,但实际开发中建议使用try-with-resources或显式关闭方法替代finalize(),因其可靠性不高。

ultramand的博客,重生之我在cad上二次开发猛猛敲C#代码~ 1801

finalize()方法

finalize()方法

qq_55105067的博客 2215

【JVM】finalize() 方法的定义与作用

finalize() 方法的定义与作用

hui_zai_的博客 1235

深入分析Java中finalize方法的作用和底层原理

我们手动调用多少次不影响JVM的行为 若JVM检测到finalized状态的对象变成unreachable,回收其内存(I),若对象并未覆盖finalize方法,JVM会进行优化,直接回收对象(O)执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。大致描述一下finalize的运行流程:当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。

m0_71777195的博客 1039

Java 为什么弃用 finalize() ?

为何弃用 finalize ?

JavaJasper的博客 2377

java中finalize

finalize()方法是Object类中提供的一个方法,在GC准备释放对象所占用的内存空间之前,它将首先调用finalize()方法。其在Object中定义如下: protected void finalize() throws Throwable { } finalize()是由FinalizerThread线程处理的,每一个即将被回收的并且包含有finalize()方法的对象都会在正...

zyzn1425077119的博客 2593

理解finalize()-析构函数的替代者【转载】

http://www.microsoft.com/china/msdn/archives/technic/develop/vj/0515c.asp 理解finalize()-析构函数的替代者by Tim Gooch在许多方面,Java 类似于 C++。Java 的语法非常类似于 C++,Java 有类、方法和数据成员;Java 的类有构造函数; Java 有异常处理。但是,如果你使

shines77 的博客 1693

finalize() 方法

Override// 在这里执行清理操作System.out.println("对象被垃圾回收了。");

m0_53271024的博客 1420

java中finalize()方法

finalize 垃圾回收机器(Garbage Collection),也叫GC,垃圾回收器主要有一下特点: 当对象不再被程序所使用的时候,垃圾回收器将会将其回收 垃圾回收是在后台运行的,我们无法命令垃圾回收器马上回收资源,但是我们可以告诉他可以尽快回收资源(System.gc()和Runtime.getRuntime().gc()) 垃圾回收器在回收某个对象的时候,首先会调用该对象的finalize()方法 GC主要针对堆内存 单例模式的缺点 finalize()是Object里面的一个方法,当一个堆

南宫沉梦博客 3万+

【有料】Java学习笔记—— finalize() 方法

1、垃圾回收 2、finalize()的定义和作用 3、finalize()的隐藏问题 4、finalize()方法的一般格式 5、finalize()的执行过程(生命周期) 6、实例 1、垃圾回收 Java的垃圾回收器只会释放由我们new出来的内存堆块,那些不是由new出来的“特殊内存”,垃圾回收器是不会管理的。 所谓的特殊内存指通过JNI用C/C++向系统申请的内存,这些内存如果不手动去清除就会一直占据在内存中。 而且,垃圾回收本身就有开销,所以虚拟机不会经常GC,只有当内存快要耗尽的

daobuxinzi的博客 383
上一篇: Tomcat中配置和使用JNDI
下一篇: 把一个普通应用程序变为win2000(NT)中的服务
net2003
博客等级 码龄24年 0粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值