2016-06-21 7 views
3

以下のコード行を実行しようとしています。私の理解は、#1と#2の両方が文字列プール内の文字列を生成する必要があるため、両方の実行に違いはないはずですが、ヒープダンプを解析すると、intern()の文字列がStringプール(限られた数の文字列オブジェクトで解釈できますが)#1の文字列がヒープ上に生成されている(ヒープダンプに多数の文字列オブジェクトが存在するため)、システムは前のケースよりも高速にメモリを使い果たしています。誰かがそれがなぜそう説明することができますか?私はjava 6を使用して、以下のコード行を実行しています。場合文字列プールで二重引用符を使用して生成された文字列が生成されない

import java.util.LinkedList; 

public class LotsOfStrings { 

private static final LinkedList<String> LOTS_OF_STRINGS = new  LinkedList<String>(); 

public static void main(String[] args) throws Exception { 
    int iteration = 0; 
    while (true) { 
     for (int i = 0; i < 100; i++) { 
      for (int j = 0; j < 1000; j++) { 
       String s= "String " + j; 
       LOTS_OF_STRINGS.add(s); // #1 
       //LOTS_OF_STRINGS.add(new String("String " + j).intern()); //#2 
      } 
     } 
     iteration++; 
     System.out.println("Survived Iteration: " + iteration); 
     Thread.sleep(100); 
    } 
} 

ヒープダンプオブジェクトのスクリーンショットの場合の場合のインターン intern

ヒープダンプオブジェクトのスクリーンショット#1

string

+0

文字列プールからの参照を取得しました。それ以外の場合は、プールで使用できる場合のみ、ヒープに文字列を作成します。 – Nir

+0

内部ループの最初の実行中に、1000の一意のStrings String 0 .... to .... String 999を生成する必要があります。この後、プログラムは、最初の実行時に作成された参照を、参照は文字列プールで利用できるはずですか? – Vyas

答えて

1

あなたは、それをインターンせずに文字列を作成した場合、それだけでヒープに行く。したがって、等しい文字列のコピーが複数存在する可能性があります。あなたが文字列をインターンにすると、それぞれの等価クラスに対して1つの文字列しか存在しません。

同じjの文字列"String" + jを複数回作成すると、文字列をインターンにすることなくメモリを消費します。

インターンはメモリを節約しますが、すべての文字列が何らかの種類のHashSetに保持され、文字列を作成することはそのHashSetに既に存在する場合に検索することを意味するためです。

注:一部の文字列は自動的に中断されます。ソースコード内の文字列リテラル。

+1

あなたは文字列s = "nothing"として作成された文字列を意味しますか?文字列プールに自動的に作成されませんか? new演算子(String s = new String( "nothing"))を使用して文字列を作成すると、ヒープ上に作成され、二重引用符(String s = "nothing")を使用して文字列を作成すると、 permgen空間の文字列プールにデフォルトが作成されます。 stringのintern()呼び出しを使用して、文字列をヒープから文字列プールに移動できます。私の理解で何かが間違っていると私を修正してください。 – Vyas

+1

私の知る限り、文字列はコンパイル時定数( "String" + jはそうではありません)の場合にのみ、自動的にインターンされます。私が間違っていれば、私に適切な情報源を指摘してください。 –

+0

これは、文字列がStringプールで生成される時定数をコンパイルする必要があることを知らなかったことです。ご協力いただきありがとうございます。 – Vyas

関連する問題