Java 9のコンパクト文字列

こんにちは! 現在、9番目のグループ「Java Developer」 (および計画の10番目のグループが突然12月31日に立っています)で次のセットを開き、興味深い資料と公開レッスンを準備しました。



行きましょう。



Javaアプリケーションで使用されるメモリの量を減らしたいですか? Java 9で使用可能なコンパクトな文字列を使用してパフォーマンスを改善する方法をご覧ください。



Java SE 9の一部としてJVM(正確にはOracle HotSpot)に導入されたパフォーマンス改善の1つは、コンパクトな文字列であることが判明しました。 彼らの仕事は、文字列オブジェクトのサイズを小さくすることです。これにより、アプリケーションが消費するメモリの総量(フットプリント)を減らすことができます。 その結果、ガベージコレクションに費やす時間を削減できます。







この関数は、ほとんどのアプリケーションがLatin-1文字のみを使用するため、多くのStringオブジェクトは各文字をエンコードするのに2バイトを必要としないという観察に基づいています。 したがって、これの代わりに:



/**       */ private final char value[];
      
      





java.lang.String



には、これがあります。



 private final byte[] value; /** *        * {@code value}.      : * * LATIN1 * UTF16 * * @implNote     .    * “”,   String - .   *      . */ private final byte coder;
      
      





つまり、この関数は、 char



配列(各要素が2バイトを使用)の値を、エンコードを決定するための追加のバイト(Latin-1またはUTF-16)を含むバイト配列に置き換えます。 つまり、Latin-1文字のみを使用するほとんどのアプリケーションでは、ヒープの半分しか使用されません。 ユーザーは違いに気付かないでしょうが、 StringBuilder



などの関連APIは自動的にこれを利用します。



Stringオブジェクトのサイズの観点からこの変更を示すために、ヒープ上のオブジェクトの構造を視覚化するためのシンプルなユーティリティであるJava Object Layoutを使用します。 この観点から、参照だけではなく、配列のフットプリント(上記の値変数に格納されている)に関心があります(文字配列参照のようなバイト配列参照は4バイトを使用します)。 以下のコードは、JOL GraphLayout



を使用して情報を表示します。



 public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } }
      
      



)toFootprint()); public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } }





上記のコードをJava 8で実行してからJava 9で実行すると、違いが示されます。



 $java -version java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@4554617cd footprint: COUNT AVG SUM DESCRIPTION 1 432 432 [C 1 24 24 java.lang.String 2 456 (total) ... $java -version java version "9" Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@73035e27d footprint: COUNT AVG SUM DESCRIPTION 1 224 224 [B 1 24 24 java.lang.String 2 248 (total)
      
      





java.lang.Stringの内部コンポーネント(ヘッダーとリンク)の24バイトサイズを無視すると、そのコンパクトさにより、サイズがほぼ2倍に減少していることがわかります。

上記の行を、UTF-16文字を使用する別の行(たとえば、\ u0780)に置き換えて、上記のコードを再起動すると、コンパクトさが使用されなくなるため、Java 8とJava 9の両方が同じフットプリントを表示します。



-XX:-CompactStrings



java



コマンドに渡すことにより、この機能を無効にでき-XX:-CompactStrings







いつものように、私たちはここであなたのコメントや質問を待っているだけでなく、あなたを公開レッスンに招待します。



All Articles