博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
清理:终结处理和垃圾回收
阅读量:4319 次
发布时间:2019-06-06

本文共 1374 字,大约阅读时间需要 4 分钟。

 

程序员都了解初始化的重要性,但常常会忘记同样也重要的清理工作。在java中有垃圾回收器负责回收无用对象占据的内存资源,但是也有特殊的情况:假定你的对象(并非使用new)获得了一个“特殊”的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道该什么释放该对象的这块“特殊”内存。为了应对这种情况,java允许在类中定义一个名为finallize()的方法。它的工作原理“假定”是这样的:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finallize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

 

这里有一个潜在的编程陷阱,因为有些程序员(特别是C++程序员)刚开始可能会把finallize()当做C++中的析构函数。所以有必要明确区分一下:在C++中,对象一定会被销毁(如果程序中没有缺陷的话);而Java里的对象并非总是被垃圾回收。或者换句话说:

 

       对象可能不被垃圾回收;

       垃圾回收并不等于“析构”;

       垃圾回收只与内存有关;

 

只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。如果程序执行结束,并且垃圾回收器一直都没有释放你创建的任何对象的存储空间,则随着程序的退出,那些资源也会全部交还给操作系统。这个策略是恰当的,因为垃圾回收本身也有开销,要是不适用它,那就不用支付这部分开销了。

 

适用垃圾回收器唯一的原因是为了回收程序不再使用的内存。所以对于有关垃圾回收有关的任何行为来说(尤其是finallize()方法),它们也必须同内存及其回收有关。

 

这是否意味着如果对象中含有其他对象,finallize()就应该明确释放那些对象呢?不是这样的,无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。

 

之所以要使用finallize(),是由于在分配内存时可能采用了类似C语言中的做法,而非Java中的通常用法,这种情况主要发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。本地方法目前只支持C和C++,但是它们可以调用其它语言写的代码,所以实际上可以用任何代码。在非Java代码中,也许会调用C的malloc()函数系列来分配存储空间,而且除非调用了free()函数,否则存储空间将得不到释放,从而造成内存泄露。当然,free()是C和C++的函数,所以需要在finallize()中调用本地方法来释放它。

 

记住:不要过多的使用finallize()方法,它不是进行普通的清理工作的合适场所。

 

 

必须实施的清理动作:

Java中不允许创建局部对象,必须使用new创建对象。在Java中,也没有用于释放对象的delete,因为垃圾回收器会帮你释放存储空间。甚至可以肤浅的认为,正是由于垃圾收集机制的存在,使得Java没有析构函数。然而,随着学习的深入,就会明白垃圾回收器并不能完全代替析构函数。(而且绝对不能直接调用finallize(),所以这也不是一种解决方案。)如果希望进行释放存储空间之外的清理工作,还是得明确调用某个恰当的Java方法,这就等同于使用析构函数了,只是没有析构函数方便。

转载于:https://www.cnblogs.com/dasenlin/archive/2013/01/19/2868057.html

你可能感兴趣的文章
bloc控制读写文件
查看>>
微信小程序
查看>>
洛谷 P1059 明明的随机数
查看>>
window自动任务实现数据库定时备份
查看>>
Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)
查看>>
javascript操作cookie
查看>>
深入理解HTTP协议(转)
查看>>
NHibernate讲解
查看>>
剑指offer-二叉树中和为某一值的路径
查看>>
spark算子
查看>>
(转)Linux服务器SNMP常用OID
查看>>
USB各种模式 解释
查看>>
数据访问-----ADO.NET 小结和练习
查看>>
Linux lsof详解
查看>>
子组件给父组件传数据
查看>>
unix/linux下的共享内存、信号量、队列信息管理
查看>>
Hilbert先生旅馆的故事
查看>>
采访吴岳师兄有感 by 王宇飞
查看>>
LVS简略介绍
查看>>
hdu 1021 Fibonacci Again
查看>>