Javaの新しい節目として、JDK 27がGeneral Availability、つまり一般提供の段階に入った。今回は機能追加の派手さよりも、リリースが予定どおり安定版に着地したことに意味がある。開発途中の機能をどこまで積み上げたのか、そしてJava 27がどんな方向を向いているのかを確認するにはちょうどいいタイミングだと思う。とくに今回は、暗号、メモリ効率、並行処理、開発者向け観測機能といった、実運用に直結しやすい領域が目立っている。
OpenJDKのMark Reinholdは、Java 27の参照実装であるJDK 27が正式にGeneral Availabilityになったと告知した。今回GAになったのは、20 Augustに第2のRelease Candidateとして出された build 35 だ。そこからP1 bug、つまり最優先で対応すべき重大障害が報告されなかったため、その build 35 がそのままGA buildとして確定し、本番利用に向く状態になったという説明になっている。
公開先としては、OracleがGPL licensed OpenJDK buildを https://jdk.java.net/27 で提供していると案内されている。ほかのベンダーからのbuildも、近いうちに出てくるだろうと添えられている。OpenJDKのリリース告知らしく、単に「出た」で終わらず、どの実装が基準になっているのかをはっきり示しているのが印象的だ。
このリリースには9件のJEPが含まれる。番号でいうと、523「Make G1 the Default Garbage Collector in All Environments」、527「Post-Quantum Hybrid Key Exchange for TLS 1.3」、531「Lazy Constants (Third Preview)」、532「Primitive Types in Patterns, instanceof, and switch (Fifth Preview)」、533「Structured Concurrency (Seventh Preview)」、534「Compact Object Headers by Default」、536「JFR In-Process Data Redaction」、537「Vector API (Twelfth Incubator)」、538「PEM Encodings of Cryptographic Objects (Third Preview)」だ。これに加えて、いつものように数百件の小さな改善と数千件のbug fixも入っている、と説明されている。
要するに今回の告知は、Java 27が完成版として出たという宣言であり、同時に、次の数年を見すえた機能群がどこまで育っているかを示す一覧でもある。最後にReinholdは、設計、実装、バグ修正、早期アクセス版のテストに関わったすべての人へ謝意を述べて締めている。
今回のJDK 27でまず目を引くのは、流行りの機能名ではなく、G1 GCが全環境でデフォルトになる点だと思う。Javaを使う側からすると、デフォルトGCの変更は「使わなければ関係ない」話ではない。多くのプロジェクトは明示的にGCを選ばずに走っているし、JDKの標準設定が変わると、性能や停止時間の体感がじわっと変わる。G1はすでに広く使われてきたが、全環境でのデフォルト化は、Javaの標準体験をそちらに寄せる強い意思表示に見える。
その一方で、Post-Quantum Hybrid Key Exchange for TLS 1.3が入っているのはかなり象徴的だ。これは将来の量子計算機を見すえた暗号移行の一歩で、今すぐ全員の通信が危なくなるという話ではない。ただ、長期にわたって保護されるべき通信では、「今暗号化しておけば安全」という前提だけでは足りなくなる。Javaがこうした領域を標準ランタイムの更新として入れてくるのは、エンタープライズ向け言語としての責務をかなり意識しているように見える。
JDK 27には、完成品ばかりが並んでいるわけではない。Lazy ConstantsはThird Preview、Primitive Types in Patterns, instanceof, and switchはFifth Preview、Structured ConcurrencyはSeventh Preview、PEM Encodings of Cryptographic ObjectsもThird Previewだし、Vector APIはTwelfth Incubatorだ。ここから分かるのは、Javaが「安定しているから変わらない言語」ではなく、かなり慎重に機能を育て続けているということだと思う。
とくにStructured ConcurrencyがSeventh Previewまで来ているのは興味深い。並行処理はJavaの長年の課題で、書きやすさと安全性の両方をどう確保するかがずっと難しかった。ここまで何度もpreviewを重ねるのは、まだ完成させるには検証が足りないという判断なのだろう。雑に急がない姿勢は好感が持てるが、ユーザーから見ると「いつ正式になるのか」が見えにくいもどかしさもある。Javaの進化は速さより、壊さずに育てることを優先しているのだと感じる。
534のCompact Object Headers by Defaultは、名前の地味さに比べて効き目が大きそうな項目だと思う。オブジェクトヘッダは、Java VMが各オブジェクトに持たせる管理情報で、普段は意識しないがメモリ使用量やキャッシュ効率に影響する。これがデフォルトでコンパクトになるなら、巨大サービスやメモリ制約のある環境では地味に効いてくる可能性がある。
もちろん、こういう変更は万能薬ではない。オブジェクトのサイズが小さくなれば必ず速くなる、という単純な話ではないし、JVM内部の最適化との相性もある。けれど、Javaが長く抱えてきた「メモリを食う」というイメージに対して、ランタイム側がまだ改善余地を持っているのは重要だ。新しい言語機能を足すだけでなく、昔からある実行時の土台を削れるところは削る。その両輪で進んでいるのが、今回のリリースの面白さではないかと思う。
536のJFR In-Process Data Redactionも、実務ではかなり気になる。JFRはJava Flight Recorderのことで、実行中のアプリの挙動を記録・分析する仕組みだ。そこにin-processでのdata redaction、つまり機微情報の伏せ字や除去の仕組みが入ると、性能調査や障害解析をしながらも、ログや記録データに残してはいけない情報を扱いやすくなる。大規模運用では「調べたいが、見せられない」という問題がよくあるので、この方向性はかなり現実的だ。
一方で537のVector APIはTwelfth Incubatorだ。長く incubator を重ねていることからも分かる通り、これはJavaが数値計算やSIMD寄りの処理で競争力を高めるための取り組みだが、まだ成熟しきってはいない。ここで重要なのは、Javaがただ守りに入っているわけではなく、観測性と高速化の両方を同時に磨いていることだと思う。運用しやすさと速度の両立は、クラウド時代のJavaにとってかなり本質的なテーマだろう。
このリリースを見て強く感じるのは、Java 27は派手な転換点というより、長く使うための手入れを一段進めた版だということだ。暗号は将来に備え、メモリは少しでも軽くし、並行処理はまだ慎重に育て、観測性は実運用の制約に合わせる。しかもGAまでの道筋は、最終RCのbuild 35から重大障害が出なかったことで固められている。安定して出せること自体が、成熟したプラットフォームの価値なのだと思う。
Javaはしばしば「枯れた技術」と見られるが、こうして見ると、実際にはかなり継続的に更新されている。しかも流行語を追うのではなく、企業システムが本当に困る場所に手を入れているのが一貫している。新しい文法だけで話題になる言語ではないが、だからこそ、見えにくい土台の改善が効いてくる。今回のJDK 27は、その地味さの中に強さがあるリリースだと感じる。
参考: Java 27 / JDK 27: General Availability - announce - openjdk.org