知识大全 Java中的finalize详解

Posted

篇首语:勇敢,事会成功;勤劳,幸福必来。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java中的finalize详解相关的知识,希望对你有一定的参考价值。

Java中的finalize详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  程序员都了解初始化的重要性 但常常会忘记同样重要的清除工作 毕竟 谁需要清除一个int 呢?但在使用程序库时 把一个对象用完后就 弃之不顾 的做法并非总是安全的 当然 Java有垃圾回收器来回收无用对象占据的内存资源 但也有特殊情况 假定你的对象(并非使用 new)获得了一块 特殊 的内存区域 由于垃圾回收器只知道释放那些经由 new分配的内存 所以它不知道该如何释放该对象的这块 特殊 内存 为了应对这种情况 Java允许你在类中定义一个名为finalize( )的方法 它的工作原理 应该 是这样的 一旦垃圾回收器准备好释放对象占用的存储空间 将首先调用其 finalize( )方法 并且在下一次垃圾回收动作发生时 才会真正回收对象占用的内存 所以要是你打算用 finalize( ) 就能在 垃圾回收时刻 做一些重要的清除工作

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

   . 对象可能不被回收

   . 垃圾回收并不等于 析构

  牢记这些 你就能远离困扰 这意味着在你不再需要某个对象之前 如果必须执行某些动作 那么你得自己去做 Java并未提供 析构函数 或相似的概念 要做类似的清除工作 你必须自己动手创建一个执行清除工作的普通方法 例如 假设某个对象在创建过程中 会将自己绘制到屏幕上 要是你不明确地从屏幕上将其擦除 它可能永远得不到清除 如果在

  finalize( )里加入某种擦除功能 当 垃圾回收 发生时(不能保证一定会发生) finalize( )得到了调用 图像就会被擦除 要是 垃圾回收 没有发生 图像就会一直保留下来

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

  finalize( )用途何在?

  此时 你已经明白了不该将finalize( )作为通用的清除方法 那么 finalize( )的真正用途是什么呢?

  这引出了要记住的第三点

   .垃圾回收只与内存有关

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

  但这是否意味着要是对象中含有其他对象 finalize( )就应该明确释放那些对象呢?不——无论对象是如何创建的 垃圾回收器都会负责释放对象占据的所有内存 这就将对 finalize( )的需求限制到特殊情况之下 你通过某种非 创建对象 的方式为对象分配了存储空间 不过 你也看到了 Java中一切皆为对象 那这种特殊情况是怎么回事呢?

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

  至此 你或许已经明白了不要过多地使用finalize( )的道理了 对 它确实不是进行普通的清除工作的合适场所 那么 普通的清除工作应该在哪执行呢?

  你必须执行清除

  为清除一个对象 用户必须在进行清除的时刻调用执行清除动作的方法 听起来似乎很简单 但却与C++中的 析构函数 的概念稍有抵触 在C++中 所有对象都会被销毁 或者说 应该 被销毁 如果在C++中创建了一个局部对象(就是在堆栈上创建 Java中可不行) 此时的销毁动作发生在以 右花括号 为边界的 此对象作用域的末尾处进行 如果对象是

  用new创建的(类似于Java) 那么当程序员调用C++的delete( )时(Java没有这个命令) 就会调用相应的析构函数 如果程序员忘了 那么永远不会调用析构函数 就会出现内存泄露 对象的其他部分也不会得到清除 这种错误很难跟踪 这也是让 C++程序员转向 Java的一个主要因素

  相反 Java不允许创建局部对象 你必须使用new 在Java中 也没有 delete 来释放对象 因为垃圾回收器会帮助你释放存储空间 甚至可以肤浅地认为 正是由于垃圾收集机制的存在 使得 Java 没有析构函数 然而 随着学习的深入 你就会明白垃圾回收器的存在并不能完全代替析构函数 (而且你绝对不能直接调用finalize( ) 所以这也不是一个恰当的

  途径 )如果你希望进行除释放存储空间之外的清除工作 你还是得明确调用某个恰当的Java方法 这就等同于使用析构函数了 而且没有它方便

  记住 无论是 垃圾回收 还是 终结 都不保证一定会发生 如果Java虚拟机(JVM)并未面临内存耗尽的情形 它是不会浪费时间在回收垃圾以恢复内存上的

  终结条件

  通常 你不能指望finalize( ) 你必须创建其它的 清除 方法 并且明确地调用它们 看来 finalize( )只能存在于程序员很难用到的一些晦涩用法里了 不过 finalize( )还有一个有趣的用法 它并不依赖于每次都要对finalize( )进行调用 这就是对象 终结条件 的验证

  当你对某个对象不再感兴趣 也就是它可以被清除时 这个对象应该处于某种状态 使它占用的内存可以被安全地释放 例如 要是对象代表了一个打开的文件 在对象被回收前程序员应该关闭这个文件 只要对象中存在没有被适当清除的部分 你的程序就存在很隐晦的错误 finalize( )的价值在于可以用来最终发现这种情况 尽管它并不总是会被调用 如果某次

  finalize( )的动作使得bug被发现 那你就可据此找出问题所在——这才是你真正关心的

  以下是个简单的例子 示范了可能的使用方式

  class Book

  boolean checkedOut = false;

  Book(boolean checkOut)

  checkedOut = checkOut;

  

  void checkIn()

  checkedOut = false;

  

  public void finalize()

  if(checkedOut)

  System out println( Error: checked out );

  // Normally you ll also do this:

  // super finalized();

  

  

  public class TerminationCondition

  public static void main(String[] args)

  Book novel = new Book(true);

  // Proper cleanup:

  novel checkIn();

  // Drop the reference fet to clean up:

  new Book(true);

  // Force garbage collection & finalization:

  System gc();

  

  

  本例的终结条件是 所有的Book对象在被当作垃圾回收前都应该被签入(check in) 但在main( )方法中 由于程序员的错误 有一本书未被签入 要是没有 finalize( )来验证终结条件 将很难发现这种错误

cha138/Article/program/Java/hx/201311/26018

相关参考

知识大全 避免使用finalizer()函数

  Java中的finalizer()函数不同于c++中的destrutors函数在java中不需要我们手动finalizer来释放资源我们只需令他们=null即可即使手动调用finalizer函数我

知识大全 Java ME中的Math.pow()方法使用详解

JavaME中的Math.pow()方法使用详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 java垃圾回收gc和finalize的区别

cha138/Article/program/Java/JSP/201405/30758

知识大全 Java中Static、this、super、final用法

Java中Static、this、super、final用法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 java问题,请大神指教

java问题,请大神指教?!因为这个new什么的是闭包隐式声明的方法、在里面调用外部变量的时候、外部的变量需要final修饰、但是这个该死的i是变化的、故而不能使用final、于是矛盾产生、故而使用中

知识大全 用finally关键字来避免资源漏洞

  现象  在用JDBC访问某个数据库并读出一个ResultSet数据记录集时如果记录数太大则会占用客户端(运行java程序的机器)的大量内存(如果客户端是某个大企业的营业部门的代理点分机则有可能ja

知识大全 Java Reflection (JAVA反射)详解

JavaReflection(JAVA反射)详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 java中Class对象详解

java中Class对象详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  java中把生成Cl

知识大全 Java输入输出流详解

Java输入输出流详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  stream代表的是任何有

知识大全 Java对各种文件的操作详解

Java对各种文件的操作详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  java中提供了io