当前位置:七道奇文章资讯编程技术Java编程
日期:2011-03-22 16:17:00  来源:本站整理

必须实施解除[Java编程]

赞助商链接



  本文“必须实施解除[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
为排除一个对象,那个对象的用户必须在但愿举行排除的地址调用一个排除办法.这听起来仿佛很简单做到,但却与C++“破坏器”的概念稍有冲突.在C++中,全部对象城市破坏(排除).大概换句话说,全部对象都“应当”破坏.若将C++对象成立成一个本地对象,比方在仓库中成立(在Java中是不大概的),那么排除或破坏工作就会在“完毕花括号”所代表的、成立这个对象的作用域的末尾举行.若对象是用new成立的(近似于Java),那么当程序员调用C++的delete号令时(Java没有这个号令),就会调用呼应的破坏器.若程序员忘掉了,那么永久不会调用破坏器,我们终究得到的将是一个内存“漏洞”,别的还包含对象的其他部份永久不会得到排除.
相反,Java不答应我们成立本地(部分)对象——无论若何都要利用new.但在Java中,没有“delete”号令来释放对象,因为垃圾汇集器会帮忙我们自动释放存储空间.所以假如站在对比简化的态度,我们可以说恰是由于存在垃圾汇集机制,所以Java没有破坏器.但是,随着今后学习的深化,就会知道垃圾汇集器的存在并不能完好消除对破坏器的需求,大概说不能消除对破坏器代表的那种机制的需求(并且绝对不能直接调用finalize(),所以应尽大概避免用它).若但愿履行除释放存储空间之外的其他某种情势的排除工作,仍旧必须调用Java中的一个办法.它等价于C++的破坏器,只是没后者便利.
finalize()最有效处的地方之一是察看垃圾汇集的历程.下面这个例子向大家展示了垃圾汇集所阅历的历程,并对前面的报告举行了总结.
//: Garbage.java
// Demonstration of the garbage
// collector and finalization

class Chair {
  static boolean gcrun = false;
  static boolean f = false;
  static int created = 0;
  static int finalized = 0;
  int i;
  Chair() {
    i = ++created;
    if(created == 47) 
      System.out.println("Created 47");
  }
  protected void finalize() {
    if(!gcrun) {
      gcrun = true;
      System.out.println(
        "Beginning to finalize after " +
        created + " Chairs have been created");
    }
    if(i == 47) {
      System.out.println(
        "Finalizing Chair #47, " +
        "Setting flag to stop Chair creation");
      f = true;
    }
    finalized++;
    if(finalized >= created)
      System.out.println(
        "All " + finalized + " finalized");
  }
}

public class Garbage {
  public static void main(String[] args) {
    if(args.length == 0) {
      System.err.println("Usage: \n" +
        "java Garbage before\n  or:\n" +
        "java Garbage after");
      return;
    }
    while(!Chair.f) {
      new Chair();
      new String("To take up space");
    }
    System.out.println(
      "After all Chairs have been created:\n" +
      "total created = " + Chair.created +
      ", total finalized = " + Chair.finalized);
    if(args[0].equals("before")) {
      System.out.println("gc():");
      System.gc();
      System.out.println("runFinalization():");
      System.runFinalization();
    }
    System.out.println("bye!");
    if(args[0].equals("after"))
      System.runFinalizersOnExit(true);
  }
} ///:~

上面这个程序成立了很多Chair对象,并且在垃圾汇集器开始运行后的某些时刻,程序会终止成立Chair.由于垃圾汇集器大概在任什么时刻间运行,所以我们不能精确知道它在什么时刻启动.因此,程序用一个名为gcrun的标志来指出垃圾汇集器能否已经开始运行.操纵第二个标志f,Chair可奉告main()它应终止对象的生成.这两个标志都是在finalize()内部设置的,它调用于垃圾汇集期间.
另两个static变量——created以及finalized——辨别用于跟踪已成立的对象数目以及垃圾汇集器已举行完收尾工作的对象数目.最后,每个Chair都有它自己的(非static)int i,所以能跟踪理解它具体的编号是多少.编号为47的Chair举行完收尾工作后,标志会设为true,终究完毕Chair对象的成立历程.
全部这些都在main()的内部举行——在下面这个循环里:

while(!Chair.f) {
new Chair();
new String("To take up space");
}

大家大概会迷惑这个循环什么时刻会停下来,因为内部没有任何改变Chair.f值的语句.但是,finalize()进程会改变这个值,直至终究对编号47的对象举行收尾处理.
每次循环历程中成立的String对象只是属于额外的垃圾,用于吸引垃圾汇集器——一旦垃圾汇集器对可用内存的容量感到“慌张不安”,就会开始关注它.
运行这个程序的时刻,供应了一个号令行自变量“before”大概“after”.此中,“before”自变量会调用System.gc()办法(强迫履行垃圾汇集器),同时还会调用System.runFinalization()办法,以便举行收尾工作.这些办法都可在Java 1.0中利用,但通过利用“after”自变量而调用的runFinalizersOnExit()办法却只有Java 1.1及后续版本供应了对它的支持(注释③).注意可在程序履行的任什么时刻候调用这个办法,并且收尾程序的履行与垃圾汇集器能否运行是无关的.

③:不幸的是,Java 1.0采取的垃圾汇集器筹划永久不能精确地调用finalize().因此,finalize()办法(分外是那些用于关闭文件的)事实上常常都不会得到调用.目前有些文章声称全部收尾模块城市在程序退出的时刻得到调用——即便到程序中止的时刻,垃圾汇集器仍未针对那些对象采纳行动.这并非真实的情形,所以我们根本不能期望finalize()能为全部对象而调用.分外地,finalize()在Java 1.0里几近毫无用处.

前面的程序向我们揭暴露:在Java 1.1中,收尾模块必定会运行这一答应已成为实际——但前提是我们明确地强迫它采纳这一操作.若利用一个不是“before”或“after”的自变量(如“none”),那么两个收尾工作都不会举行,并且我们会得到象下面这样的输出:
Created 47

Created 47
Beginning to finalize after 8694 Chairs have been created
Finalizing Chair #47, Setting flag to stop Chair creation
After all Chairs have been created:
total created = 9834, total finalized = 108
bye!
因此,到程序完毕的时刻,并非全部收尾模块城市得到调用(注释④).为强迫举行收尾工作,可先调用System.gc(),再调用System.runFinalization().这样可排除到目前为止没有利用的全部对象.这样做一个稍显奇特的地方是在调用runFinalization()之前调用gc(),这看起来仿佛与Sun公司的文档阐明有些冲突,它声称首先运行收尾模块,再释放存储空间.但是,若在这里首先调用runFinalization(),再调用gc(),收尾模块根本不会履行.

④:到你读到本书时,有些Java虚拟机(JVM)大概已开始表现出差别的行为.

针对全部对象,Java 1.1有时之所以会默许为跳过收尾工作,是由于它认为这样做的开销太大.不管用哪类办法强迫举行垃圾汇集,都大概注意到比没有额外收尾工作时较长的时间耽误.
  以上是“必须实施解除[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 必须实施解除
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .