Java
 Computer >> コンピューター >  >> プログラミング >> Java

Java 9のコンパクト文字列(Compact Strings)とは?仕組みと内部実装の変化を解説

コンパクト文字列(Compact Strings)の概要

Java 9以降、JVMはコンパクト文字列(Compact Strings)と呼ばれる新機能によって、文字列のメモリ使用量を最適化するようになりました。従来のchar[]配列の代わりに、文字列をbyte[]配列として表現できるようになったのが最大の特徴です。

エンコーディングにはUTF-16またはLatin-1(ISO-8859-1)が使用され、これにより1文字あたり1バイトまたは2バイトで文字を格納できます。JVMがその文字列にISO-8859-1/Latin-1の範囲内の文字のみが含まれていることを検出した場合、内部的には1文字あたり1バイトで保持されます。日本語などのマルチバイト文字を含む文字列は、従来どおりUTF-16で扱われます。

判定のタイミングと有効化・無効化

文字列がコンパクト形式で表現されるかどうかは、文字列の生成時に判定されます。この機能はデフォルトで有効になっており、無効化したい場合は起動オプションに-XX:-CompactStringsを指定します。

なお、この機能を無効にした場合でも、以前のchar[]ベースの実装に戻るわけではありません。すべての文字列が引き続きUTF-16として保存されます。

内部実装の比較:Java 8 vs Java 9

// Java 8の場合
public class String {
    private final char[] value; // 文字列内の文字をchar型配列で保持
    ---------
}

// Java 9の場合
public class String {
    private final byte[] value; // 文字列内の文字をbyte型配列で保持
    private final byte coder;   // 1文字あたり1バイトか2バイトかを示すフラグ
    ---------
}

上記のコード例から分かるように、Java 9ではStringクラスの内部フィールドがchar[]からbyte[]へ変更され、さらにエンコーディング方式を識別するためのcoderフィールドが追加されています。この変更により、Latin-1のみで構成される文字列(英語圏のテキストなど)では、メモリ消費量を約半分に削減できます。

まとめ

  • Java 9から導入されたコンパクト文字列により、文字列はbyte[]として格納される
  • Latin-1文字のみの文字列は1文字1バイト、それ以外はUTF-16で2バイトとなる
  • デフォルトで有効であり、-XX:-CompactStringsで無効化可能
  • ヒープメモリの大幅な節約につながる最適化機能である
  1. JavaのStringIndexOutOfBoundsExceptionとは?発生原因と対処法をわかりやすく解説

    StringIndexOutOfBoundsExceptionとはJavaにおいて、文字列(String)は一連の文字を格納するために使用され、オブジェクトとして扱われます。文字列は、java.langパッケージに含まれるStringクラスによって表現されます。文字列の作成方法は主に2つあります。1つは他のオブジェクトと同様にnewキーワードを使用する方法、もう1つはプリミティブ型のようにリテラルを直接代入する方法です。String stringObject = new String(Hello how are you); String stringLiteral = Welcome to T

  2. Javaで文字列を比較する方法|equals()とequalsIgnoreCase()の使い分けを徹底解説

    Javaで文字列の等価性を比較する際は、Stringクラスが提供するequalsメソッドまたはequalsIgnoreCaseメソッドを使用するのが基本です。この記事では、それぞれのメソッドの使い方に加えて、==演算子で文字列を比較してはいけない理由についても詳しく解説します。 equals()メソッドで文字列を比較する 2つの文字列を比較し、大文字と小文字の違いまで厳密に判定したい場合はequals()メソッドを使用します。 次のコード例では、2つのStringインスタンスが大文字小文字を含むすべての文字において一致しているかどうかを判定しています。 public class Compare