国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

必須執行清除

2019-11-18 13:21:14
字體:
來源:轉載
供稿:網友

  為清除一個對象,那個對象的用戶必須在希望進行清除的地點調用一個清除方法。這聽起來似乎很輕易做到,但卻與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.   }
   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 1.1有時之所以會默認為跳過收尾工作,是由于它認為這樣做的開銷太大。不管用哪種方法強制進行垃圾收集,都可能注重到比沒有額外收尾工作時較長的時間延遲。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 郓城县| 沙田区| 汉阴县| 革吉县| 钦州市| 云南省| 外汇| 平顺县| 吴忠市| 许昌市| 阿巴嘎旗| 桑日县| 虎林市| 大方县| 岗巴县| 陕西省| 斗六市| 广灵县| 汶上县| 义马市| 普陀区| 濮阳县| 广德县| 龙游县| 定襄县| 黄骅市| 延长县| 奉化市| 阳城县| 邯郸市| 荔浦县| 新沂市| 南投县| 阜新市| 九寨沟县| 高雄县| 沙雅县| 扎赉特旗| 大同市| 甘肃省| 花垣县|