世界を動かす技術を、日本語で。

プロジェクト「ヴァルハラ」の解説:10年の成果がJDK 28に結実するまで

2026年6月19日原文(jvm-weekly.com)

概要

  • OracleエンジニアLois Foltanが JEP 401: Value Classes and Objects のOpenJDK統合を発表
  • JDK 28で プレビュー機能 として導入、デフォルトでは無効
  • Valhallaプロジェクト の長年の課題解決への第一歩
  • Javaのパフォーマンスと設計モデルの 根本的な進化
  • 本稿はValhallaの歴史と技術的背景を 体系的に解説

JEP 401: Value ClassesとValhallaプロジェクトの全貌

  • 2024年6月15日、OracleのLois Foltanが JEP 401: Value Classes and Objects のOpenJDK本体リポジトリへの統合を正式に確認
  • JDK 28をターゲットとし、 197,000行以上のコード と1,816ファイルが追加される大規模変更
  • 現段階では プレビュー版 であり、デフォルトで無効化
  • Brian Goetzによると「これはValhallaの第一段階のみ」であり、今後さらなる進化が予定
  • 長年「実装されない」と言われてきたが、ついに大きな一歩を踏み出す

Valhallaプロジェクトの目的とJavaの根本的課題

  • Valhallaのスローガンは「 クラスのように書けて、intのように動く
  • Javaでは 参照型プリミティブ型 が分断されており、柔軟性とパフォーマンスの両立が困難
  • 例:Point p = new Point(1, 2)の場合、pは実体ではなく ヒープ上のアドレス を指す
  • 大量のオブジェクトを扱うと メモリレイアウトが「ふわふわ」 (fluffy)になり、キャッシュ効率が低下
  • Project Lilliput はオブジェクトヘッダーの縮小に取り組むが、根本解決には至らず

メモリ密度とパフォーマンス

  • 近年、CPUとメモリアクセス速度の差が拡大し、 キャッシュミス によるパフォーマンス低下が深刻化
  • データが密に並ぶことで キャッシュライン ごとの効率的な読み込みが可能
  • 参照型オブジェクトの配列では、 ポインタ追跡によるキャッシュミス が頻発

Escape Analysisとその限界

  • JVMの エスケープ解析 により、一部のオブジェクトはヒープ割り当てを回避可能
  • しかし、解析が 脆弱かつ予測不能 で、コード変更やJDKアップデートでパフォーマンスが大きく変動
  • 経験豊富なJVM開発者は、エスケープ解析を 「ボーナス」扱い とし、基盤にはしない

手動によるプリミティブ最適化の問題

  • 高速化のため、 Colorクラスをbyte配列で手動管理 する手法が一般的
  • しかし、 安全性や可読性を犠牲 にするため、バグや意図しないデータ破壊のリスクが増大

Valhallaの歴史と設計思想の変遷

  • 2014年に公式始動、 James Gosling が「6つのPhDが絡み合ったプロジェクト」と評す
  • Java誕生時から 値型導入 の構想はあったが、技術的困難で断念
  • 5つの異なるプロトタイプ を経て現在の設計に到達

Q WorldとL Worldの違い

  • 初期案「 Q World」では値型をプリミティブと完全に分離し、型システムが複雑化
  • 2019年頃、「 L World」で値型と参照型を同じキャリア(L記述子)で扱う統一モデルに成功
  • 言語モデルとJVMモデルの分離 がプロジェクトの鍵となる

モデルと用語の変遷

  • Stage 1: value types (曖昧な初期案)
  • Stage 2: inline classes (identity有無で区別、final制約追加)
  • Stage 3: primitive classesと二重投影モデル (Point.val/Point.refなど、複雑さが増し断念)
  • Stage 4: value classesとvalue objects (JEP 401で確定、identity無しの参照型として定義)

現在のJEP 401と今後の展望

  • value修飾子 による新しいクラス宣言方式
  • インスタンスは identityを持たないvalue object
  • 非null制約 は別JEP(Null-Restricted Value Class Types)で今後対応予定
  • 古い記事や資料で「primitive classes」等の記述があれば 現行仕様と異なる 点に注意
  • JEP 401は JEP 402(Enhanced Primitive Boxing) や各種早期アクセスビルドと連携
  • 12年間は「 アイデアの淘汰」の歴史であり、保守可能な仕様に絞り込まれた

まとめ

  • JEP 401は、 Javaの設計とパフォーマンスの根本的転換点
  • Valhallaプロジェクトは「 便利なクラスと高速なプリミティブの両立」という長年の課題に挑戦
  • JDK 28でのプレビュー導入は、今後の Java言語進化の基盤 となる可能性

Hackerたちの意見

Javaの値型の進化について、テクノサスペンスを一本作れそうだよね。メーリングリストを読んだり、関連する動画を全部見たりしてきたけど、デザインをJavaらしいものにまとめ上げたのは本当に感動的だよ。しかも、値型が何を意味するのか、どこで最適化ができるのかを深く理解して、細かい部分まで掘り下げてるのがすごい。

最終的にValhallaに組み込まれたものには、たくさんの努力があったのは感謝してるけど、 > モデルは強力だけど、精神的には重い っていうのは違うと思う!この解釈がnull安全性の議論を完全に潰しちゃってる。nullにならない変数があるっていうのは、特にラベルがしっかり付いてるから、そんなに頭を悩ませることじゃないよね。 > チームは「ユーザーのためにモデルを簡素化する、パフォーマンスの限界を犠牲にしても」という教訓に忠実で、最終的にこの二元性を解体したけど、ユーザーには簡素化されてたはず。こういう態度やプロセスがあると、Javaが賢い方向に進むとはあまり思えない。プログラミング言語の型システムは、数値しか扱えないCPUに対して開発者に便利な保証を与えるべきなのに。「精神的に重い」って理由でオプショナルな(!)安全性の保証を減らす理由はないよ。彼らは半分は認めてるしね。 > 言語モデルとJVMモデルは100%重なる必要はない

この態度やプロセスがあると、Javaが賢い方向に進むとはあまり思えない。 それには同意するよ。Javaの運営はかなり不十分に見える、特にMSなどが最初から正しい決定をしていた.NETと比べると。今のOracleにJavaに対する価値や関心はあるのかな?会社は今やデータセンターやコンピューティングビジネスにシフトしてるみたいで、レガシーな活動のための付属物と膨大な負債がある。Oracleの中でまだ利益が出てるのは法務部門と芝刈り機部門だけなんじゃないかって時々思う。

これは主にパフォーマンスとメモリレイアウトのためのもので、Javaの安全性の保証が向上するわけではないよ。

つまり、あなたの不満はブロガーについてで、Java言語についてじゃないってこと?それに、nullマーカーも来るよ:https://openjdk.org/jeps/8303099 ただ、彼らは物事を段階的に進めなきゃいけないんだ。このPRは値クラス/オブジェクトを導入するもので、すでに20万行もあるよ。

Nullableは、Railway Orientated Programmingの別の状態なんだよね。だから、2012年から解決済みのことを言語に直接入れる理由はないよ。要は、Aに行くかBに行くか、列車の状態によるだけ。もし、存在するかしないかの概念で言語戦争が起きてるなら、それは需要があるってことだし、言語がその需要をうまく扱えてないか、扱ったとしても頭がパンクしちゃうってことだよ。 > Value > Errorstates > Null > IoExceptions > WeirdOsStatesNeededToHandleUpstairs https://fsharpforfunandprofit.com/rop/ パイソンたちが言ったように:さっさとやれ!

この解釈がnull安全性の議論を完全に潰してしまう。変数がnullにならないと言っても、それは特に頭を使う区別じゃないよね。すべてがしっかりラベル付けされてるから。君はこれが何を指しているのか見逃してると思う。これはnull安全性の話じゃなくて(それは無関係)、Integer/intに似た参照/値のプロジェクションを持つことについてなんだ。Valhallaチームが最終的にやったのは、各型に対してアイデンティティのあるプロジェクションとないプロジェクションを持つ代わりに、値型はアイデンティティを持たず、Integerとintは同義になり、メモリのレイアウトは文脈と最適化の決定に基づいて自動的に決まるってこと。だから、プリミティブラッパー(Integerみたいな)の==のセマンティクスが変更されたんだ。今は「参照プロジェクション」か「値プロジェクション」どちらを使うかに依存しないから。 > 「精神的に負担が大きすぎる」という言い訳で、提供できるオプショナル(!)な安全保証を減らす理由はないよ。ここで起こったことじゃない。

そうだね、この点に関してJavaは100%終わってる。ひどい決断をして、それを「一貫性」のために続けてるんだ。

Java界隈では.NETの存在を認めるのはタブーだって知ってるけど、これって.NETの構造体とどう違うの?値型、ジェネリックの特化、ボクシング…ざっと見た感じ、同じ選択をしてるように見える。

機能的には違うよ。Javaは(今となっては)古い慣習に追いついてるだけ。 > C#の構造体はアイデンティティとミューテーションを持っているから、代入や引き渡しの際のコピーのセマンティクスを正確に定義する必要があり、プログラマーには重いモデルを提供し、ランタイムには自由度が少なくなる。っていうのは、彼らが説明してることとはあまり合ってない。確かに、Javaのクラス参照の意味でのアイデンティティはないけど、特定のアドレスにあるユニークな構造体としてのアイデンティティはもちろんあるよ。これはJavaの名称についての細かい議論に過ぎない。

そのことについては記事にセクションがあるよ。私にとって、C/C#の構造体は変更可能でコピー渡しされるけど、値クラスは変更不可で値渡しされる。Javaでスタック割り当てはできないと思う。

C#には実際にかなりの落とし穴があって、Javaはそれを明示化しようとしてるんだ。C#が低レベルの視点からCをほぼコピーしたのに対し、Javaの人たちは高レベルでアプローチして、どの制約がどんな利点をもたらすかを詳細に分析したんだ。だから、他の言語ではstruct/classの分類がバイナリなのに対して、Javaはもっと細かい制御を許して、基盤となるドメインのセマンティクスを反映させてる。結果的に、structには特に並列コンテキストで多くの危険があることがわかったんだ。

Hacker Newsで議論の続きを見る