0

文字列は不変であり、文字列プールで管理されます。このプールがどのように管理されているか知りたいです。アプリケーションで多数の文字列リテラルが使用されている場合 (追加、置換操作などの変更が多い場合は文字列ビルダーを使用する必要があることを理解しています)、プールは新しい文字列オブジェクトを何度も再作成しないことで、アプリケーションのパフォーマンスを向上させます。ただし、プールに存在する同じオブジェクトを使用すると、文字列は不変であり、そうしても悪影響はないため、これは可能です。

私の質問は、これString Poolがどのように管理されているかです。いくつかの「k」文字列の頻度が非常に高く、一度作成されて再び使用されていない他の文字列オブジェクトがほとんどない場合。他の新しい文字列リテラルが使用されている可能性があります。

このような場合、String Pool は LRU キャッシュのように動作し、最新の使用済みリテラルへの参照を保持し、使用されていない古い文字列をプールから削除しますか?

String プールにはサイズがありますか、それともアプリケーションで制御できますか?

編集 :

通常、実装するカスタム オブジェクト プールにサイズを指定します。Sting Pool に LRU のような機能がないのはなぜでしょうか。これが特徴だったのかもしれません。大きな文字列の場合も問題はありませんでした。しかし、私はそれが実装された方法だと感じていますが、なぜそこにないのかを知りたかっただけです。つまり、何らかの正当な理由でそこにないことを意味します。この機能を使用すると、いくつかの悪影響が生じるでしょう. 誰かがそれらの悪影響に光を当てることができれば、それは良いことです.

4

1 に答える 1

3

文字列プールは LRU キャッシュではありません。これは、GC を実行しない限りエントリが取り出されないためです。

String プールのエントリを取得するには 2 つの方法があります。文字列リテラルは自動的にそこに移動し、プールに既に存在しString.intern()ない限り、新しいエントリを追加できますString。その場合、それへの参照が返されます。

値への参照がなくなると、値intern()ガベージ コレクションされます。これは、文字列リテラル (文字列定数など) の場合、 ed されたものよりも少し難しくなる可能性があります。

実装は、Java 6 と Java 8 の間で (さらにはマイナー バージョン間でも) 大幅に変更されました。String プールのデフォルトのサイズは明らかに ですが、 (Java 7 以降) パラメータ1009で変更できます。-XX:StringTableSize=Nこのサイズは内部ハッシュ テーブルのテーブル サイズなので、大量に使用している場合は大きく調整できますintern()(文字列リテラルの場合は十分なはずです)。サイズは呼び出しの速度にのみ影響し、intern()インターンできる文字列の量には影響しません。

基本的intern()に、(おそらく正当な理由で) 大量に使用していない限り、String プールについて心配する理由はほとんどありません。特に に保存されなくなったPermGenため、簡単に発生することはありOutOfMemoryErrorsません。

ソース

于 2016-04-25T09:56:34.227 に答える