1. 概要

この記事では、 Project Valhalla –その歴史的な理由、開発の現在の状態、そしてそれが日々のテーブルにもたらすものを見ていきますJavaリリースされたら開発者。

2. Valhallaプロジェクトの動機と理由

オラクルのJava言語アーキテクトであるBrianGoetzは、彼のトークの1つで、Valhallaプロジェクトの主な動機の1つは、Java言語とランタイムを最新のハードウェアに適応させたいという願望であると述べました 。 Java言語が考案されたとき(執筆時点で約25年前)、メモリフェッチと算術演算のコストはほぼ同じでした。

今日では、これはシフトしており、メモリフェッチ操作は算術操作よりも200倍から1,000倍高価です。 言語設計の観点から、これは、ポインターフェッチにつながる間接が全体的なパフォーマンスに悪影響を与えることを意味します。

アプリケーション内のほとんどのJavaデータ構造はオブジェクトであるため、Javaはポインターを多用する言語と見なすことができます(ただし、通常、それらを直接表示または操作することはありません)。 このポインタベースのオブジェクトの実装は、オブジェクトIDを有効にするために使用されます。オブジェクトID自体は、ポリモーフィズム、可変性、ロックなどの言語機能に利用されます。 これらの機能は、本当に必要かどうかに関係なく、すべてのオブジェクトにデフォルトで付属しています。

ポインターにつながるIDのチェーンと、間接につながるポインターに続いて、間接にはパフォーマンス上の欠点があるため、論理的な結論は、それらを必要としないデータ構造のポインターを削除することです。 ここで値型が作用します。

3. 値型

値型の考え方は、純粋なデータ集合体を表すことです。 これには、通常のオブジェクトの機能を削除することが含まれます。 つまり、アイデンティティのない純粋なデータがあります。 もちろん、これは、オブジェクトIDを使用して実装できる機能も失われることを意味します。 したがって、等式の比較は、状態に基づいてのみ行うことができます。したがって、表現型ポリモーフィズムを使用することはできず、不変またはnull許容でないオブジェクトを使用することもできません。

オブジェクトIDがなくなったため、オブジェクトと比較して、ポインタをあきらめ、値型の一般的なメモリレイアウトを変更できます。 クラス間のメモリレイアウトの比較を見てみましょうおよび対応する値型点。 

通常のPointクラスのコードと対応するメモリレイアウトは次のようになります。

final class Point {
  final int x;
  final int y;
}

一方、値型Pointのコードと対応するメモリレイアウトは次のようになります。

value class Point {
  int x;
  int y
}

これにより、JVMは値型を配列やオブジェクト、および他の値型にフラット化できます。次の図では、Pointを使用した場合の間接化の悪影響を示しています。配列内のクラス:

一方、ここでは、値型 Point[]の対応するメモリ構造を確認できます。

また、JVMは、ヒープに値型を割り当てる代わりに、スタック上で値型を渡すことができます。 つまり、これは、intやfloatなどのJavaプリミティブと同様の実行時動作を持つデータ集約を取得していることを意味します。

ただし、プリミティブとは異なり、値型にはメソッドとフィールドを含めることができます。 インターフェイスを実装して、それらを汎用タイプとして使用することもできます。 したがって、2つの異なる角度から値型を見ることができます。

  • より高速なオブジェクト
  • ユーザー定義のプリミティブ

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

4. スペシャライズドジェネリックス

言語プリミティブを生成する場合、現在、intの場合はIntegerfloatの場合はFloatなどのボックス型を使用しています。 このボクシングは、間接参照の追加レイヤーを作成します。これにより、そもそもパフォーマンス向上のためにプリミティブを使用するという目的が無効になります。

したがって、既存のフレームワークやライブラリのプリミティブ型に特化した多くの専門分野があります。 IntStream また ToIntFunction 。 これは、プリミティブを使用することによるパフォーマンスの向上を維持するために行われます。

したがって、特殊なジェネリックは、これらの「ハック」の必要性を排除するための取り組みです。 代わりに、Java言語は、オブジェクト参照、プリミティブ、値型、さらには void など、基本的にすべての汎用型を有効にしようと努めています。

5. 結論

ProjectValhallaがJava言語にもたらす変更を垣間見ることができました。 主な目標の2つは、パフォーマンスの向上とリークの少ない抽象化です。

パフォーマンスの向上は、オブジェクトグラフをフラット化し、間接を削除することで対処されます。 これにより、メモリレイアウトがより効率的になり、割り当てとガベージコレクションが少なくなります。

より優れた抽象化には、汎用型として使用した場合により類似した動作をするプリミティブとオブジェクトが付属しています。

Project Valhallaの初期のプロトタイプは、既存の型システムに値型を導入しており、コードネームはLW1です。

Project Valhallaの詳細については、対応するプロジェクトページとJEPを参照してください。