Java Valhallaプロジェクト

1. 概要

この記事では、https://wiki.openjdk.java.net/display/valhalla/Main [Project] https://wiki.openjdk.java.net/display/valhalla/Main[Valhalla] –を見ていきます。それの歴史的理由、開発の現状、そしてそれがリリースされた後の日々のJava開発者のテーブルにもたらすもの。

2. ヴァルハラプロジェクトの動機と理由

OracleのJava言語アーキテクトであるBrian Goetzは、https://www.youtube.com/watch?v = A-mxj2vhVAA [talks]の1つで、Valhallaプロジェクトの主な動機の1つは、 Java言語とランタイムから最新のハードウェア*。 Java言語が考案されたとき(執筆時点で約25年前)、*メモリフェッチと算術演算のコストはほぼ同じでした。*
現在、これは変化しており、メモリフェッチ操作は算術操作の200倍から1,000倍の費用がかかります。 *言語設計の観点から、これは、ポインターフェッチにつながるインダイレクションが全体的なパフォーマンスに悪影響を与えることを意味します。*
アプリケーション内のほとんどのJavaデータ構造はオブジェクトであるため、Javaをポインターが重い言語と見なすことができます(通常、直接表示したり操作したりすることはありません)。 オブジェクトのこのポインターベースの実装は、オブジェクトの識別を可能にするために使用されます。オブジェクトの識別自体は、ポリモーフィズム、可変性、ロックなどの言語機能に活用されます。 これらの機能は、実際に必要かどうかに関係なく、すべてのオブジェクトにデフォルトで付属しています。
ポインターにつながるIDチェーンと、インダイレクションにつながるポインターに続いて、インダイレクションにはパフォーマンス上の欠点があるため、論理的な結論は、それらを必要としないデータ構造のそれらを削除することです。 これは、値型が作用する場所です。

3. 値タイプ

値型の考え方は、*純粋なデータ集計を表す*ことです。 これには、通常のオブジェクトの機能の削除が伴います。 したがって、アイデンティティのない純粋なデータがあります。 これは、もちろん、オブジェクトIDを使用して実装できる機能も失われていることを意味します。 結果として、*等価比較は状態に基づいてのみ行われます。*したがって、表現多型を使用することはできず、不変オブジェクトまたは非ヌルオブジェクトを使用することはできません。
オブジェクトのアイデンティティがなくなったため、オブジェクトと比較して、ポインタを放棄し、値型の一般的なメモリレイアウトを変更できます。 クラス_Point_と対応する値型_Pointの間のメモリレイアウトの比較を見てみましょう。 _
通常の_Point_クラスのコードと対応するメモリレイアウトは次のとおりです。
final class Point {
  final int x;
  final int y;
}
link:/uploads/point-class-memory.svg []
一方、値型_Point_のコードと対応するメモリレイアウトは次のようになります。
value class Point {
  int x;
  int y
}
link:/uploads/point-value-type-memory.svg []
*これにより、JVMは値型を配列およびオブジェクト、および他の値型にフラット化できます。*次の図では、配列で_Point_クラスを使用した場合の間接性の悪影響を示しています。
link:/uploads/java-point-vaue-type-array.svg []
一方、ここでは、値型_Point [] _の対応するメモリ構造が表示されます。
link:/uploads/java-point-vaue-type-array-values.svg []
また、JVMがヒープに値タイプを割り当てる代わりに、スタックで値タイプを渡すことができます。 *最後に、これは、_int_や_float_などのJavaプリミティブに類似した実行時の動作を持つデータ集約を取得していることを意味します*
ただし、プリミティブとは異なり、値型にはメソッドとフィールドを含めることができます。 インターフェイスを実装して、ジェネリック型として使用することもできます。 したがって、2つの異なる角度から値タイプを見ることができます。
  • より高速なオブジェクト

  • ユーザー定義のプリミティブ

    ケーキの追加のアイシングとして、値タイプをボックス化せずに汎用タイプとして使用できます。 これは、他の大きなプロジェクトヴァルハラ機能である特殊なジェネリックに直接つながります。

4. 特殊ジェネリック

言語プリミティブを生成する場合、現在、_int_の場合は_Integer _、_ float_の場合は_Float_などのボックス化された型を使用します。 このボックス化により、間接的な追加レイヤーが作成されるため、そもそもパフォーマンス向上のためにプリミティブを使用する目的が無効になります。
そのため、_IntStream <T> _や_ToIntFunction <T> _など、既存のフレームワークとライブラリのプリミティブ型に特化した多くの特殊化が見られます。 これは、プリミティブを使用した場合のパフォーマンスの向上を維持するために行われます。
そのため、特殊なジェネリックは、それらの「ハック」の必要性を取り除く努力です。 代わりに、Java言語は、オブジェクト参照、プリミティブ、値型、さらには_void_など、基本的にすべての汎用型を有効にするよう努めています。

5. 結論

Project ValhallaがJava言語にもたらす変更を垣間見ることができました。 * 2つの主な目標は、パフォーマンスの向上と漏れの少ない抽象化です。*
パフォーマンスの向上は、オブジェクトグラフを平坦化し、間接参照を削除することで解決されます。 *これにより、メモリレイアウトがより効率的になり、割り当てとガベージコレクションが少なくなります。*
*より優れた抽象化には、ジェネリック型として使用した場合により類似した動作を持つプリミティブとオブジェクトが含まれます。*
既存の型システムに値型を導入するProject Valhallaの初期のプロトタイプのコード名はhttps://wiki.openjdk.java.net/display/valhalla/LW1[LW1]です。
Project Valhallaの詳細については、対応するプロジェクトページとJEPを参照してください。