1. ホーム
  2. java

Java 8 の文字列重複排除機能

2023-09-09 18:12:52

質問内容

以下 String は各文字が2バイトを消費するため、Java (他の言語と同様) では多くのメモリを消費します。 文字列の重複排除 これは char 配列が文字列と final の内部であることを利用し、JVM がそれらをいじくり回すことができるようにします。

私が読んだのは この例 を読みましたが、私はプロのJavaプログラマーではないので、コンセプトを理解するのに苦労しています。

以下はその内容です。

文字列の複製については様々な戦略が検討されましたが、現在実装されているものは次のようなアプローチです。 現在実装されているものは、次のようなアプローチになっています。ガベージコレクタが String オブジェクトにアクセスするときは常に ガベージコレクタがStringオブジェクトにアクセスすると、char配列に注目します。 配列に注目します。ガベージコレクタがStringオブジェクトを訪れるたびに、char配列に注目し、そのハッシュ値を取って、配列への弱い参照と一緒に保存します。 配列への弱い参照とともに保存します。同じハッシュ値を持つ別のStringを見つけるとすぐに 同じハッシュ値を持つ別の文字列を見つけるとすぐに、それらを一文字ずつ比較します。もしそれらが同じように一致すれば が一致した場合は、一方の文字列が変更され、もう一方の文字列の配列を指すようになります。 を指すようになります。最初の文字配列は、もはや参照されることはありません。 ガベージコレクトされます。

このプロセス全体はもちろんオーバーヘッドをもたらしますが、厳しい制限によって制御されています。 厳しい制限によって制御されています。例えば、ある文字列がしばらく重複していることが発見されなかった場合、その文字列はもうチェックされません。 が見つからなければ、それはもうチェックされません。

最初の質問です。

それは最近Java 8アップデート20で追加されたので、このトピックに関するリソースがまだ不足しています。 String によって消費されるメモリを削減するためにどのように役立つか、いくつかの実用的な例を共有できませんか?

編集してください。

上のリンクに書いてあります。

同じハッシュコードを持つ別の文字列を見つけるとすぐに 一文字ずつ比較します。

2つ目の質問です。

2つのハッシュコード String が同じであれば Strings はすでに同じであるなら、なぜ比較するのか charchar であることがわかると、2つの String が同じハッシュコードを持つことがわかったら?

どのように解決するのですか?

電話帳があり、その中には String firstNameString lastName . そして、電話帳の中で、10万人の人が同じ firstName = "John" .

データベースやファイルからデータを取得するため、これらの文字列はインターンされないので、JVMのメモリにはchar配列の {'J', 'o', 'h', 'n'} 10万回、ジョン文字列ごとに1回です。これらの配列はそれぞれ、たとえば 20 バイトのメモリを使用するため、これらの 100k Johns は 2 MB のメモリを使用します。

重複排除を行うと、JVMは"John"が何度も重複していることを認識し、これらすべてのJohn文字列が同じ基礎となる文字配列を指すようにし、メモリ使用量を2MBから20バイトに削減します。

より詳細な説明は JEP . 特に

多くの大規模なJavaアプリケーションは、現在メモリがボトルネックになっています。測定によると、この種のアプリケーションの Java ヒープ ライブ データセットの約 25% が String オブジェクトによって消費されていることが示されています。さらに、これらの String オブジェクトの約半分は重複しており、重複しているということは string1.equals(string2) が真であることを意味します。ヒープ上に重複した String オブジェクトを持つことは、本質的に単なるメモリの無駄遣いです。

[...]

実際に期待される利益は、約10%のヒープ削減で終わります。この数字は、広範囲のアプリケーションに基づいた計算された平均値であることに注意してください。特定のアプリケーションのヒープ削減は、上下に大きく異なる可能性があります。