2011-10-24 14 views
11

PS:finalize()に依存せず、正しくクリーンアップする方法を知っています。JVM/GCはプログラム/スレッド終了時に `finalize()`を呼び出しますか?

Javaは、プログラムの終了時に適切なガベージコレクションが行われることを保証しませんか?

など。いくつかのデータを頻繁にシリアライズするのではなく、キャッシュに保存しておきたいと思っていますが、何らかの理由でクラッシュを除いてプログラムが正常に終了すると、キャッシュはDB/file/someに書き込まれるという希望でfinalize()を実装しました。 finalize()メソッドで自分のコードで保存します。しかし、以下の少しの実験によると、JVMはメモリを "正常に"クリーンアップしないように思われます。ただ終了します。

Java spec(プログラム終了を参照)は、終了時にmemory/gcがどのように処理されるかを示しています。または、私は仕様の別のセクションを見ていなければなりませんか?私は、何finalize()が呼び出されていないいずれかSystem.gc()コメントを解除した場合

  • は、Windows上で7

    public class Main { 
    
         // just so GC might feel there is something to free.. 
        private int[] intarr = new int[10000]; 
    
        public static void main(String[] args) { 
         System.out.println("entry"); 
         Main m = new Main(); 
         m.foo(); 
         m = new Main(); 
         // System.gc(); 
         m.foo(); 
         m = null; 
         // System.gc(); 
         System.out.println("before System.exit(0);"); 
         System.exit(0); 
        } 
    
        @Override 
        protected void finalize() throws Throwable { 
         System.out.println("finalize()"); 
         super.finalize(); 
        } 
    
        public void foo() { System.out.println("foo()"); } 
    } 
    
    /* 
    * Prints: 
    * entry 
    * foo() 
    * foo() 
    * before System.exit(0); 
    */ 
    

    バリエーション1.6.0.27 64ビットを用いて、例えば以下の(端部における出力)、テイク。

  • System.gc()の両方をコメント解除すると、finalize()が2回呼び出されます。
  • System.exit()の呼び出しの有無は、finalize()の呼び出しに影響しません。
+0

あなたが持っている問題は、プログラムの任意の時点で不正に死ぬことができるということです。また、再起動時にクリーンアップが必要な場合もあります。 –

答えて

10

いいえ、Javaでは、プログラムの終了時にGCがトリガーすることは保証されません。終了時に操作を実行するには、Runtime.addShutdownHookメソッドを使用します。 thisを読んでくださいSPECが言っていることに関するSunの記事。

Javaプラットフォームの仕様は、ガベージコレクションが実際にどのように機能するか について非常にいくつかの約束をします。ここでは、Java Virtual マシン仕様(JVMS)がメモリ管理について言わなければならないことがあります。

ヒープは、仮想マシンの起動時に作成されます。 オブジェクトのヒープストレージは、自動ストレージ管理システム(ガベージコレクタとして として知られています)によって再利用されます。オブジェクトは決して明示的に解放されません。 Java仮想マシンは、自動ストレージ 管理システムの特定のタイプを想定しておらず、ストレージ管理手法は、実装者のシステム要件に従って を選択することができます.1 が混乱しているように見えるかもしれませんが、ガベージコレクションモデルは厳密ではない実際に重要で有用なのは です。厳密に定義されたごみは、すべてのプラットフォームで実装することが不可能な場合があります。 同様に、有用な最適化を排除し、プラットフォームのパフォーマンスを長期的に損なう可能性があります。

必要なガベージコレクタの動作の完全な定義が含まれています誰の場所はありませんが、GCモデルの多くは、暗黙的にJava言語 仕様とJVMS内のセクションの数を介して指定 です。正確な プロセスが続いについての保証はありませんが、すべての準拠した仮想マシンは、この章で説明した基本的な オブジェクトのライフサイクルを共有しています。

+0

それはどこですか(スペックなど)ですか? – Kashyap

+1

あなたが提供した説明はまだGCが終了時に完了していないと述べていませんが、JVMに残されていることを十分に明確にしていると思います。 。 – Kashyap

+1

「GCは必ずしも終了時に実行されません」読み込む仕様には負の文はありません。仕様で意図的に曖昧と私が引用され、幅広い文が記載されているものすべてです。 –

3

Runtime.runFinalizersOnExit()を参照してください。これは非推奨であり、残りの解説に注意してください。私はあなたが合法的にそれがデフォルトでオフになっていることすべてのことから推測することができると思いますが、あなたはまた、オンさせることができることに注意してください。

関連する問題