2016-04-25 6 views
0

文字列は不変であり、文字列プールで管理されます。私はこのプールがどのように管理されているかを知りたい。アプリケーションで多数のStringリテラルが使用されている場合(append、replace操作などの変更が多い場合はString builderを使用する必要があります)、Poolは新しいStringオブジェクトを何度も再作成しないことでアプリケーションのパフォーマンスを向上させますプール内に存在する同じオブジェクトを使用すると、これは可能です。文字列は不変であり、そうすることで悪影響はありません。JavaのString PoolはLRUキャッシュのように動作しますか?

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

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

文字列プールにはサイズがありますか、アプリケーションで制御できますか?

編集:

通常、実装するカスタムオブジェクトプールにサイズを指定します。なぜ私はLRUのような機能がスティングプールにはないのだろうと思っています。これは機能でした。大きな文字列の場合にも問題はないでしょう。しかし、私はそれが実装されている方法を感じるが、私はちょうどその理由がない、私はいくつかの妥当な理由のためにそこにないということを知りたがっていました。もしそれらの悪影響を軽視する人がいれば、それは良いことになるでしょう。

答えて

3

文字列プールはLRUキャッシュではありません。なぜなら、GC'dがなければエントリは取り出されないからです。

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

は、文字列リテラル(例えば、文字列定数)のためintern() EDたものより少し硬くすることができ、それらへの参照が、存在しない場合ガベージコレクションです。

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

intern()を使用していない限り(おそらく理由がある)、Stringプールについて心配する理由はほとんどありません。特にPermGenに格納されていないので、それはもう簡単にもうOutOfMemoryErrorsを引き起こすことはできません。

Source

関連する問題