Java 8 update 20 for String deduplication( 詳細 )の機能について読んでいますが、これが基本的にString.intern()
になるかどうかはわかりません。廃止されました。
このJVM機能にはG1ガベージコレクターが必要であることを知っていますが、これは多くの人にとってオプションではないかもしれませんが、G1GCを使用していると仮定すると、自動重複排除の違い/利点/欠点はありますかJVMによってvs手動で文字列をintern
する必要がある(1つの明らかなものは、intern()
の呼び出しでコードを汚染する必要がないという利点です)?
OracleがG1GCをJava 9)のデフォルトGCにする可能性があることを考えると、これは特に興味深いものです。
この機能を使用すると、1000個の異なるStringオブジェクトがあり、すべて同じコンテンツ_"abc"
_である場合、JVMはそれらを内部で同じ_char[]
_を共有させることができます。ただし、1000個の異なるString
オブジェクトがまだあります。
intern()
を使用すると、String
オブジェクトが1つだけになります。したがって、メモリの節約が懸念される場合は、intern()
の方が適しています。スペースとGC時間を節約できます。
ただし、前回聞いたときは、intern()
のパフォーマンスはそれほど良くありません。 ConcurrentHashMap
...を使用する場合でも、独自の文字列キャッシュを用意する方がよい場合がありますが、確実にベンチマークする必要があります。
コメントの参照として、以下を参照してください: http://Java-performance.info/string-intern-in-Java-6-7-8/ 。これは非常に洞察に満ちた参考資料であり、多くのことを学びましたが、その結論が必ずしも「1つのサイズですべてに適合する」かどうかはわかりません。それぞれの側面は、独自のアプリケーションのニーズによって異なります。現実的な入力データを測定することを強くお勧めします。
主な要因は、おそらくあなたが何を管理しているかに依存します:
GCの選択を完全に制御できますか?たとえば、GUIアプリケーションでは、シリアルGCを使用するための強力なケースがまだあります。 (プロセスの合計メモリフットプリントははるかに少ない-適度に複雑なアプリの場合は約1GBに対して400MBと考え、使用量が一時的に急増した後など、メモリを解放する意欲がはるかに高くなります)。したがって、それを選択するか、ユーザーにオプションを提供することができます。 (ヒープが小さいままの場合、一時停止は大したことではありません)。
コードを完全に制御できますか? G1GCオプションは、編集できないサードパーティのライブラリ(およびアプリケーション!)に最適です。
2番目の考慮事項(@ZhongYuの回答による)は、_String.intern
_はString
オブジェクト自体を重複排除できるのに対し、G1GCは必然的にプライベート_char[]
_フィールドのみを重複排除できるということです。
3番目の考慮事項は、CPU使用率です。たとえば、ラップトップのバッテリー寿命への影響がユーザーにとって懸念される場合などです。 G1GCは、ヒープの重複排除専用の追加スレッドを実行します。たとえば、Eclipseを実行するためにこれを試してみたところ、起動後にCPUアクティビティが最初に増加することがわかりました(1〜2分と考えてください)が、「使用中」の小さなヒープに落ち着き、明らかではありません(目だけ-タスクマネージャーのボール)CPUオーバーヘッドまたはその後の速度低下。したがって、CPUコアの特定の割合が、大量のメモリチャーンの重複排除(中?後?)期間に使用されると思います。 (もちろん、String.interneverywhereを呼び出すと、同等のオーバーヘッドが発生する可能性があります。これもシリアルで実行されますが、...)
おそらくどこでも文字列の重複排除は必要ありません。おそらく、次のような特定のコード領域しかありません。
_String.intern
_を選択的に使用することにより、コードの他の部分(一時的または半一時的な文字列を作成する可能性があります)は代償を払いません。
そして最後に、Guavaユーティリティのクイックプラグ: Interner 、which:
他の不変タイプの
String.intern()
と同等の動作を提供します
文字列にも使用できます。メモリはおそらくパフォーマンスの最大の懸念事項である(そしてそうあるべきである)ので、これはおそらく頻繁には当てはまりません。ただし、ホットスポット領域から速度のすべての低下を絞り出す必要がある場合、私の経験では、Javaベースの弱参照です。 HashMapソリューションは、jvmオプションを調整した後でも、JVMのString.intern()
のC++実装よりもわずかですが一貫して高速に実行されます。 (そしてボーナス:異なる入力にスケーリングするためにJVMオプションを調整する必要はありません。)
ターゲットオーディエンスに関する別の決定要因を紹介したいと思います。