2013-03-05 12 views
11

は、私は次のコードがあるとします。Javaのガベージコレクション

public void process() { 
    byte[] data = new byte[size]; 
    ... // code that uses the above data 
    longProcess(); // a very long running process that does not use the data. 
} 

データはプログラムのどこにも参照されないと仮定すると、データがゴミであることを可能にするために十分にスマートJVMであります長いプロセスが実行されている間に収集されますか?そうでない場合

、この現象が発生することができます長いプロセスの前に

data = null; 

を追加するのでしょうか?

+0

おそらく、多分。 – Cubic

+0

括弧でコードを囲むことができます。 – MikeTheLiar

+0

'data = null'はガベージコレクションの対象となります。 –

答えて

6

これはJVMによって異なります。試したオラクルのJVM(1.6.0_41および1.7.0_09)のバージョンでは、デフォルトでこの最適化が実行されません。ただし、積極的な最適化を有効にすると、1.7.0_09が実行されます。

ここにありますが、私が行ってきたテストです:f2()は一貫3205回の繰り返しを管理し、一方、

public class Main { 
    public static int g() { 
     int n = 100000; 
     int arr[][] = new int[n][]; 
     for (int i = 0; i < n; ++i) { 
      try { 
       arr[i] = new int[100000]; 
      } catch (OutOfMemoryError ex) { 
       return i; 
      } 
     } 
     return -1; 
    } 
    public static void f1() { 
     int arr[] = new int[1000000]; 
     System.out.println(g()); 
    } 
    public static void f2() { 
     int arr[] = new int[1000000]; 
     arr = null; 
     System.out.println(g()); 
    } 
    public static void main(String[] argv) { 
     for (int j = 0; j < 2; ++j) { 
      for (int i = 0; i < 10; ++i) { 
       f1(); 
      } 
      System.out.println("-----"); 
      for (int i = 0; i < 10; ++i) { 
       f2(); 
      } 
      System.out.println("-----"); 
     } 
    } 
} 

デフォルト設定でJVM 1.7を使用して、f1()は一貫して、3195回の繰り返しの後にメモリ不足します。

Java 1.7.0_09と-XX:+AggressiveOpts -XX:CompileThreshold=1を使用してコードを実行した場合、画像が変更されます。両方のバージョンで3205回の反復ができます。この場合、HotSpotはこの最適化を実行します。 Java 1.6.0_41ではこれが行われていないようです。

私のテストでは、配列の範囲を制限することは参照nullを設定するのと同じ効果があり、JVMが配列をできるだけ早く収集するのに役立つと思われる場合は、おそらく好ましい選択です。

+0

あなたは積極的なオプスのフラグで遊んでみましたか? – radai

+0

@radai:あなたはどのフラグを覚えていますか? – NPE

+0

-XX:+ AggressiveOpts -XX:CompileThreshold = 1ほとんどが、コンパイルと最適化を強制しようとします。 – radai

0

データへの参照がない場合は、GCがジョブを実行します。

+0

これは質問に答えません。編集:私は途中でdownvoterではありません:) –

+0

彼が言っているのは、配列への参照がスコープ内に存在するが、それはプログラムの(長期実行)実行の残りのために使用されていません。私はその質問がよりうまく表現できると思う:「参照が存在するが使用されていなければ、データをガベージ・コレクションできるか? – asteri

1

書かれているようにコードが与えられていれば、アレイ上の配列へのスコープ参照が残っているため、longprocess()の実行中に確実にガベージコレクトされません。配列が宣言されると、その配列へのすべての参照が削除されるまでガベージコレクションの対象になりません。あなたの処理コードに応じて、それが唯一の参照ではないかもしれないが、あなたのライン

data = null; 

は、それへの一つの参照を削除します。すべての参照が削除されている場合、ガーベジコレクタはlongprocess()が戻るまでに配列のメモリを収集することができますが、これは保証されません。

0

データ配列は、処理メソッドが終了した後にのみメモリで割り当て解除されます。したがって、コンパイラでメモリの割り当てを解除する場合は、コードにdata = nullを明示的に追加する必要があります。

ガベージコレクタは有効な参照がないメモリだけを解放し、そのメモリを再度参照する方法はありません。

関連する問題