21

ガベージ コレクションについて読んでいますが、文字列リテラル ガベージ コレクションを検索すると、わかりにくい検索結果が表示されます。

次の点について説明が必要です。

  1. コンパイル時に文字列がリテラルとして定義されている場合 [例: String str = "java"] ガベージ コレクトされますか?

  2. intern メソッドを使用する場合 [例: String str = new String("java").intern()] ガベージ コレクションは行われますか? また、ポイント1の文字列リテラルとは異なる扱いになります。

  3. Stringクラスがアンロードされるときにのみ、リテラルがガベージコレクションされると言及されている場所がありますか? Stringクラスがアンロードされることはないと思うので、それは理にかなっていますか。

4

4 に答える 4

19

文字列がコンパイル時にリテラルとして定義されている場合[例:String str = "java";]、ガベージコレクションされますか?

おそらくそうではありません。Stringコードオブジェクトには、リテラルを表すオブジェクトへの1つ以上の参照が含まれます。コードオブジェクトが到達可能である限り、オブジェクトは到達可能になりStringます。

コードオブジェクトが到達不能になる可能性がありますが、動的にロードされた場合に限り、クラスローダーが破棄されます。

インターン方式[例:String str = new String("java").intern()]を使用した場合、ガベージコレクションは行われますか?

呼び出しによって返されるオブジェクトは、文字列リテラルinternを表す同じオブジェクトになります。"java""java"リテラルはクラスのロード時にインターンされます。次にString、コードスニペットで新しく構築されたオブジェクトをインターンすると、以前にインターンされた"java"文字列が検索されて返されます。)

ただし、文字列リテラルと同一ではないインターン文字列は、到達不能になるとガベージコレクションされる可能性があります。PermGenスペース、最近のすべてのHotSpotJVMでガベージコレクションされます。(Java8より前...PermGenを完全に削除します。)

また、ポイント1の文字列リテラルとは異なる方法で処理されます。

いいえ...文字列リテラルと同じオブジェクトであるため。

実際、何が起こっているのかを理解すれば、文字列リテラルも特別に扱われないことは明らかです。これは、「到達可能性」ルールの単なる適用です...

Stringクラスがアンロードされるときにのみリテラルがガベージコレクションされると言われている場所がいくつかありますか?Stringクラスがアンロードされることはないと思うので、それは理にかなっていますか。

あなたが正しいです。それは意味がありません。それが間違っていると言った情報源。(彼らが私たち自身のために言っていることを私たちが読むことができるようにあなたがURLを投稿したならそれは役に立ちます...)

于 2013-03-10T16:15:37.007 に答える
10

通常の状況では、文字列リテラルとクラスはすべて JVM の永続的な世代 (「PermGen」) に割り当てられ、通常は収集されません。インターンされた文字列 (例: mystring.intern()) は、permgen のクラスが所有するメモリ プールに格納されますString。また、ストリング プール自体がすべての文字列への参照を保持していたため、積極的なインターンによってスペース リークが発生することがありました。参照が存在しました。どうやら、少なくとも JDK 1.6 では、これは当てはまらないようです (たとえば、こちらを参照)。

permgen の詳細については、このトピックの適切な概要です。(注: そのリンクは製品に関連するブログに移動します。私はブログ、会社、または製品とは何の関係もありませんが、ブログのエントリは役に立ち、製品とはあまり関係がありません。 )

于 2013-03-10T15:57:57.940 に答える
0
  1. プログラムがメモリ内にある限り、リテラル文字列はメモリ内に残ります。
  2. strガベージコレクションされますが、作成元のリテラルはそうではありません。
  3. プログラムがアンロードされると文字列クラスがアンロードされるため、これは完全に理にかなっています。
于 2013-03-10T15:58:54.823 に答える
-3

intern()メソッドは、文字列プール内のオブジェクトの可用性をチェックします。オブジェクト/リテラル​​が使用可能な場合は、その参照が返されます。リテラルがプールにない場合、オブジェクトはperm領域(文字列プール)にロードされ、それへの参照が返されます。私たちはintern()慎重に方法を使わなければなりません。

于 2013-03-10T16:05:53.227 に答える