http://openjdk.java.net/jeps/254 をテキトーに訳した
JEP 254: Compact Strings
Author Brent Christian Owner Xueming Shen Created 2014/08/04 21:54 Updated 2015/07/16 18:49 Type Feature Status Targeted Component core-libs/java.lang Scope Implementation Discussion core dash libs dash dev at openjdk dot java dot net Effort L Duration XL Priority 2 Reviewed by Aleksey Shipilev, Brian Goetz, Charlie Hunt Endorsed by Brian Goetz Release 9 Issue 8054307 Relates to JEP 192: String Deduplication in G1 JEP 250: Store Interned Strings in CDS Archives
Summary
文字列のより効率的な内部表現を導入する。
Goals
多くの場合にパフォーマンスを向上し、かつ、すべての関連Javaおよびネイティブインタフェースと完全な互換性を保ちつつ、String
と関連クラスのメモリ効率を改善する。
Non-Goals
文字列の内部表現においてUTF-8など異なるエンコーディングを使うことは対象外。それらについては以降のJEPで研究を行うと思われる。
Motivation
String
クラスの現在の実装はchar
配列で、各文字ごとに2バイト(16ビット)を使用している。多数の異なるアプリケーションから収集したデータによれば文字列はヒープに占める割合が最も多いコンポーネントであり、そうしたString
オブジェクトのほとんどはLatin-1文字だけで構成されている。そうした文字列は格納に1バイトのみ必要であり、よって、そうしたString
オブジェクトの内部的なchar
配列の空間の半分は未使用に終わる。
Description
我々の提案としては、String
クラスの内部表現を、UTF-16のchar
配列からbyte
配列にエンコーディングフラグのフィールドを追加したものへ、変更を行う。新しいString
クラスは、文字列の内容に応じて、ISO-8859-1/Latin-1(1文字1バイト)もしくはUTF-16(1文字2バイト)いずれかでエンコードした文字列を格納する。エンコーディングフラグは使用エンコーディングを示す。
AbstractStringBuilder
, StringBuilder
, StringBuffer
などの文字列関連クラスは、HotSpotが元々持つ文字列操作に沿うように、同様な表現を使うようアップデートを行います。
これらの作業は純粋に実装の変更であり、既存のpublicインタフェースは一切変更しません。新規のpublic APIやインタフェースを追加する予定もありません。
現在までのプロトタイピングでは、メモリフットプリントの削減、GC発生の相当な減少、その他細かい場合では小規模なパフォーマンス低下、を期待できることを確認しています。
詳細については以下を参照してください。
Alternatives
我々は、-XX
フラグの有効化による、"圧縮文字列"("compressed strings")機能をJDK 6 updateリリースで取り組みました。このフラグを有効化すると、String.value
はObject
参照に変更され、7ビットのUS-ASCII文字列のみから成る文字列もしくはchar
配列のどちらか、を指すようになります。この実装は非オープンソースのため、JDKソースのメインラインと同期してメンテナンスし続けることが困難になっていました。よって削除されています。
Testing
互換性と退行テストがプラットフォームの基礎部分への変更などにおいては必要不可欠です。
また、プロジェクトのパフォーマンス目標を達成したことを確認することも必要です。メモリ削減の分析が必要です。パフォーマンステストを広範囲のワークロードで行うべきで、マイクロベンチマークにフォーカスしたものから大規模サーバまでを対象とします。
変更後の残課題の特定のため、早期テストの実施をJavaコミュニティ全体に推奨します。
Risks and Assumptions
メモリのための文字列空間の最適化は実行時パフォーマンスの観点でトレードオフが付き物です。その点はGC発生の抑制で相殺されると想定しており、一般的なサーバーベンチマークのスループットを改善可能と思われます。もしそうならない場合、メモリ削減と実行時パフォーマンスで受け入れ可能なバランスを取れる最適化を研究します。
他の関連プロジェクト、具体的にはJEP 192: String Deduplication in G1では、文字列が使用するヒープ空間の削減を行っています。重複の切り捨て同様に、もし効率的なエンコードがされれば、切り捨て後の文字列はより少ない空間の消費で済む可能性があります。本プロジェクトは労力に見合う成果が得られる、と閑雅ています。