1. ホーム

[解決済み】Java Stringのインターンとは?

2022-04-04 23:27:47

質問

とは何ですか? 文字列のインターリング をどのような場合に使用するのか、そして なぜ ?

解決方法は?

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern()

基本的に、一連の文字列に対して String.intern() を実行すると、同じ内容を持つすべての文字列が同じメモリを共有することになります。つまり、'john' が 1000 回現れる名前のリストがあったとして、intern を実行することで、実際にメモリが割り当てられるのは 'john' ひとつだけであることを保証します。

これは、プログラムのメモリ使用量を減らすのに有効です。しかし、キャッシュはJVMによって恒久的なメモリプールで維持されることに注意してください。それは通常、ヒープに比べてサイズが限られているので、あまり多くの重複した値を持っていない場合は、インターンを使用するべきではありません。


intern() を使用した場合のメモリ制約の詳細

<ブロッククオート

一方では、String の重複を削除するために を内部化します。問題は、内部化された文字列が パーマネント・ジェネレーションは、JVMの中で予約されている領域です。 クラス、メソッド、その他のJVM内部オブジェクトのような非ユーザーオブジェクトのための オブジェクトを作成します。この領域の大きさは限られており、通常 ヒープより 文字列に対してintern()を呼び出すと、その文字列は ヒープからパーマネント世代に移動してしまうので、そのリスクがあります。 PermGenのスペースが足りなくなる。

-- からです。 http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html


JDK 7から(HotSpotでの話ですが)、何かが変わりました。

JDK 7 では、インターンした文字列は Java ヒープの永久世代に割り当てられず、アプリケーションが作成した他のオブジェクトと一緒に Java ヒープの主要部分 (若い世代と古い世代として知られています) に割り当てられます。この変更により、メインのJavaヒープに存在するデータが増え、パーマネント世代に存在するデータが減るため、ヒープサイズを調整する必要が生じる可能性があります。ほとんどのアプリケーションでは、この変更によるヒープ使用量の差は比較的小さいですが、多くのクラスをロードしたり、String.intern()メソッドを多用する大規模なアプリケーションでは、より大きな差が生じます。

-- より Java SE 7 の機能と強化された点

更新:Java 7 以降、インターンした文字列はメインヒープに格納されます。 http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html#jdk7changes