10

Javaでは、

文字列定数プールの文字列リテラルは、スペースを最適化するためにランタイムのインスタンスによって作成される参照のテーブルから参照されるため、ガベージコレクションされません。

文字列リテラルプールのサイズがそれを超える場合、文字列リテラルプール内の各文字列には参照があるため、GCの対象にはなりません。JVMによってどのように処理されますか?

4

2 に答える 2

12

JavaRanchで、実際のコード例を使った長い議論があります。

一般的な出力は次のとおりです。

  1. String.intern() を使用して RUNTIME に文字列が定数プールに追加された場合、使用されなくなった後にガベージ コレクションを実行できます。ほとんどの場合、文字列プールは追加された文字列へのソフト参照のみを保持するため、それらをガベージ コレクションできます (String.intern() はネイティブ メソッドであるため、確実ではありません)。
  2. 文字列が COMPILE 時定数の場合、対応するクラスの定数プールに追加されます。したがって、クラスがアンロードされた後にのみ、ガベージ コレクションを実行できます。

あなたの質問への答えは次のとおりです。文字列定数のために OutOfMemoryError を取得する唯一の方法は、コンパイル時に計算された多くの文字列リテラルを含む多くのクラスをロードすることです。その後、最終的に PermGen スペースの最大サイズを超えることができます。ただし、これは、クラスをメモリにロードするときに発生します (たとえば、アプリケーションを開始する、プロジェクトを WebServer にデプロイする、新しいライブラリを動的にロードするなど)。

于 2012-04-19T09:45:38.283 に答える
3

文字列リテラルは、不要になったときに収集できます。多くのクラスをロードしようとすると、Maximum Perm Gen.

一般的に言えば、開発者は、文字列リテラル プールを過剰に使用せず、その代わりにデータベースまたはファイルを使用して大量のデータをロードするほど賢明です。

システムのスペースを最適化しようとして String.intern() を頻繁に使用すると、問題が発生する可能性があります。String.intern() は無料ではなく、大量 (数百万) の文字列を追加するとますます高価になります。これがパフォーマンスの問題である場合は、開発者にとって合理的に明らかなはずです。

于 2012-04-19T09:09:21.710 に答える