最近、現役で現場で Java エンジニアやっている人の話をいくつか聞いていると、Java の機能についての理解が Java 8 までで止まっている人が多い気がしました。Oracle 版の有償化やサポートライフサイクルの変更などの影響で、Java 8 の延長サポートを使っているシステムが多く、Java 9 以降の経験を積んでいる Java エンジニアがあまり増えていないのではないかな、と思っています。
ここでは、Java 9 以降 Java 13 までに追加された機能をいくつか抜粋して紹介したいと思います。
Java 14 についてはこちらの記事をご覧ください。
番町のITおじさんが書く、ITエンジニアの教養ブログです。様々なプログラミング言語やソフトウェア工学についての知識、ITやIT業界の歴史、動向などを取り上げます。
2020/04/18
Java 14 の新機能 (10) - JEP 370: Foreign-Memory Access API (Incubator)
JEP 370: Foreign-Memory Access API (Incubator)
しかし Java でも、オフヒープメモリ(Off-Heap-Memory) または外部メモリ (Foreign-Memory) と呼ばれる、ガーベジコレクタの管理外のメモリを使用する需要はあり、以前からオフヒープメモリアクセスを行う実装は存在していました。大きく分けて3つの方法があります。
Foreign-Memory Access API とは?
Java プログラムにおいて使用するメモリは、通常ヒープ領域の中から確保されます。ヒープはガーベジコレクタの管理下にあり、オブジェクトの生成に応じて必要なメモリがヒープから割り当てられ、オブジェクトが消滅したメモリはガーベジコレクタによって識別されて未使用ヒープに戻ります。しかし Java でも、オフヒープメモリ(Off-Heap-Memory) または外部メモリ (Foreign-Memory) と呼ばれる、ガーベジコレクタの管理外のメモリを使用する需要はあり、以前からオフヒープメモリアクセスを行う実装は存在していました。大きく分けて3つの方法があります。
JDK Flight Recorder で物理メモリを監視してみたけど何か変
Java 14 の新機能である、Foreign-Memory Access API の記事を書こうと思い、試しに 4GB のヒープ外メモリを割り当ててアクセスするプログラムを書いてみました。
メモリ確保状況を確認するため Java 14 の JFR Event Stream を使って、jdk.PhysicalMemory を監視してみたのですが、解放が反映される様子がありません。
top コマンドの出力を横に並べてみると、そちらではちゃんと即座に解放されていることが確認できました。その様子を動画に撮ってみました。
メモリ確保状況を確認するため Java 14 の JFR Event Stream を使って、jdk.PhysicalMemory を監視してみたのですが、解放が反映される様子がありません。
top コマンドの出力を横に並べてみると、そちらではちゃんと即座に解放されていることが確認できました。その様子を動画に撮ってみました。
2020/04/17
Java 14 の新機能 (9) - JEP 368: Text Blocks (Second Preview)
JEP 368: Text Blocks (Second Preview)
Java 13 での JEP 355: Text Blocks (Preview) を受けて、仕様を修正しての Second Preview です。まだ Preview レベルなので、明示的に有効化しないと使えません。
Java 13 での JEP 355: Text Blocks (Preview) を受けて、仕様を修正しての Second Preview です。まだ Preview レベルなので、明示的に有効化しないと使えません。
テキストブロックとは?
テキストブロックとは、複数行に渡る文字列リテラルの記法です。他の言語では、here document とか here string とか raw string とか verbatim とか呼ばれている記法です。Java 14 の新機能 (7) - JEP 359: Records (Preview)
JEP 359: Records (Preview)
record とは
Java 14 から、データを保持するための immutable なクラスを定義するための新しい構文が追加されました。それが record です。
データを保持するために、以下のような性質を持つクラスを定義することは、Java では頻繁にあります。
データを保持するために、以下のような性質を持つクラスを定義することは、Java では頻繁にあります。
- immutable であること
- コンストラクタでフィールドを全て設定し、フィールドは final
- 値を取り出すメソッドを持っていること
- final クラスであること
- hashCode, equals, toString が適切に定義されていること
とても頻繁に定義するので、IDE で自動生成したり、Lombok のような特殊な仕組みを使ったりしていました。
これからは、record がサポートしてくれます。
2020/04/14
Java 14 の新機能 (6) - JEP 358: Helpful NullPointerExceptions
JEP 358: Helpful NullPointerExceptions
NullPointerException 発生時のエラーメッセージが詳しくなりました。
NullPointerException 発生時のエラーメッセージが詳しくなりました。
使い方
今のところ、デフォルトでは無効になっていて、VM 引数を付けて有効にする必要があります。-XX:+ShowCodeDetailsInExceptionMessages を付けてください。
Java 14 の新機能 (5) - JEP 352: Non-Volatile Mapped Byte Buffers
JEP 352: Non-Volatile Mapped Byte Buffers
MappedByteBuffer は java.nio でメモリマップドI/Oを行うときに使う ByteBuffer です。その MappedByteBuffer が不揮発メモリ (Non-Volatile Memory/NVM) 向けに改良されました。
おそらく、Filesystem DAX を使って mmap で NVDIMM に直接アクセスするシチュエーションを考慮したものだと思います。
MappedByteBuffer は java.nio でメモリマップドI/Oを行うときに使う ByteBuffer です。その MappedByteBuffer が不揮発メモリ (Non-Volatile Memory/NVM) 向けに改良されました。
おそらく、Filesystem DAX を使って mmap で NVDIMM に直接アクセスするシチュエーションを考慮したものだと思います。
深夜の九段坂公園
新型コロナウイルスの蔓延で、外出しづらい日々が続いておりますね。私は人の少ない深夜に、近所の九段坂公園まで散歩してきました。
九段坂公園は以前は、地面が波打ってたり、銅像が立っているけど何の情報も無かったりと、微妙な公園でしたが、最近リニューアルを終えて綺麗で広々した感じになっています。
行ったのは 3:00AM 頃で、誰も居ないだろうと思っていたのですが、番町エリアの内側と違って靖国通り沿いは深夜でもけっこう人通りがありました。車もかなり走っていたので、ちょっとうるさいし空気悪いですね。
やっぱり散歩は大通りには出ないでおこう思いました。
2020/04/13
Blogger コンテンツに自動的に目次を付ける
Blogger 記事に自動的に目次を付けるガジェットを作ってみました。
様々な目次自動生成機構を見てみたのですが、複数記事のあるページに目次を付けたかったので、主にこちらを参考にして作ってみました。
汎用性がちゃんとあるのかどうか分かりませんが、公開したいと思います。
様々な目次自動生成機構を見てみたのですが、複数記事のあるページに目次を付けたかったので、主にこちらを参考にして作ってみました。
汎用性がちゃんとあるのかどうか分かりませんが、公開したいと思います。
2020/04/12
Java 14 の新機能 (4) - JEP 349: JFR Event Streaming
JEP 349: JFR Event Streaming
JDK Flight Recorder という機能が OpenJDK 11 から含まれています。JRockit 由来の機能で、VM 内部のイベントをファイルに記録し、VM の実行中でも終了後でも、Mission Control や JFR API を使ったプログラムでプロファイリング的に解析できるというものです。
動作中の VM に対しても使えるのですが、記録されたイベントを走査していく形の API なので、リアルタイム監視目的にはちょっと使いづらい API でした。
そこにきて今回、ストリーム形式の API が追加され、イベントドリブンな形で JFR イベントにアクセスできるようになりました。インプロセスでの JFR イベント処理はもちろん、記録されたファイルを解析するときも、どちらも EventStream という統一されたインターフェースでアクセスできます。
JDK Flight Recorder という機能が OpenJDK 11 から含まれています。JRockit 由来の機能で、VM 内部のイベントをファイルに記録し、VM の実行中でも終了後でも、Mission Control や JFR API を使ったプログラムでプロファイリング的に解析できるというものです。
動作中の VM に対しても使えるのですが、記録されたイベントを走査していく形の API なので、リアルタイム監視目的にはちょっと使いづらい API でした。
そこにきて今回、ストリーム形式の API が追加され、イベントドリブンな形で JFR イベントにアクセスできるようになりました。インプロセスでの JFR イベント処理はもちろん、記録されたファイルを解析するときも、どちらも EventStream という統一されたインターフェースでアクセスできます。
2020/04/11
Java 14 の新機能 (3) - JEP 345: NUMA-Aware Memory Allocation for G1
JEP 345: NUMA-Aware Memory Allocation for G1
NUMA とは、Non-Uniform Memory Access の略で、マルチプロセッサのコンピュータアーキテクチャの1形態です。CPU コアにメインメモリのコントローラが内包されており、メインメモリが従属する CPU コアが決まっています。CPU コアは、自分の持っているメモリ (ローカルメモリ) には高速にアクセスできますが、他コアのメモリ (リモートメモリ) へはコア間接続 (インターコネクト) 経由でアクセスするため、遅くなります。
対義語は UMA (Uniform Memory Access) で、全コアがコア外のメモリコントローラ経由でメインメモリにアクセスするようになっていて、どのコアもどのメモリへも均一のアクセス速度を持つ形態です。
Intel では Core i7 や Xeon の Nehalem 世代以降、NUMA になっています。AMD だと Opteron は NUMA です。Ryzen は NUMA も UMA も出来るというびっくり仕様。
Java VM においては、Parallel GC では以前から NUMA が考慮されていましたが、他の GC では考慮されていませんでした。今回、G1 GC で NUMA を考慮するようになりました。
具体的にはまず、各 NUMA ノードに均一にヒープを確保します。その上で、新しいオブジェクトを割り当てるときには、それを行うスレッドに紐付く NUMA ノード上のメモリを優先的に割り当てます。生存期間の短いオブジェクトは、割り当てたスレッドからのアクセスが断然多いということが経験上分かっているため、効率が良くなります。
大きいオブジェクトや古い世代のオブジェクトは、この限りではなくなります。
有効化するには、-XX:+UseNUMA オプションを付けて起動します。
NUMA とは、Non-Uniform Memory Access の略で、マルチプロセッサのコンピュータアーキテクチャの1形態です。CPU コアにメインメモリのコントローラが内包されており、メインメモリが従属する CPU コアが決まっています。CPU コアは、自分の持っているメモリ (ローカルメモリ) には高速にアクセスできますが、他コアのメモリ (リモートメモリ) へはコア間接続 (インターコネクト) 経由でアクセスするため、遅くなります。
対義語は UMA (Uniform Memory Access) で、全コアがコア外のメモリコントローラ経由でメインメモリにアクセスするようになっていて、どのコアもどのメモリへも均一のアクセス速度を持つ形態です。
Intel では Core i7 や Xeon の Nehalem 世代以降、NUMA になっています。AMD だと Opteron は NUMA です。Ryzen は NUMA も UMA も出来るというびっくり仕様。
Java VM においては、Parallel GC では以前から NUMA が考慮されていましたが、他の GC では考慮されていませんでした。今回、G1 GC で NUMA を考慮するようになりました。
具体的にはまず、各 NUMA ノードに均一にヒープを確保します。その上で、新しいオブジェクトを割り当てるときには、それを行うスレッドに紐付く NUMA ノード上のメモリを優先的に割り当てます。生存期間の短いオブジェクトは、割り当てたスレッドからのアクセスが断然多いということが経験上分かっているため、効率が良くなります。
大きいオブジェクトや古い世代のオブジェクトは、この限りではなくなります。
有効化するには、-XX:+UseNUMA オプションを付けて起動します。
2020/04/10
Java 14 の新機能 (2) - JEP 343: Packaging Tool (Incubator)
JEP 343: Packaging Tool (Incubator)
自己完結型 (つまり、Java Runtime を含んだ形) で Java アプリケーションをパッケージ化するツールです。jpackage というコマンドになっています。
Java 14 の新機能 (1) - JEP 305: Pattern Matching for instanceof (Preview)
JEP 305: Pattern Matching for instanceof (Preview)
instanceof 演算子にパターンマッチング機能が追加されました。いわゆる instanceof-and-cast idiom を書かずに済むようにするための文法拡張です。Preview なので、明示的に Preview レベルの機能を有効にしてあげないと使えません。
instanceof 演算子にパターンマッチング機能が追加されました。いわゆる instanceof-and-cast idiom を書かずに済むようにするための文法拡張です。Preview なので、明示的に Preview レベルの機能を有効にしてあげないと使えません。
Java 14 リリース
Java 14 が出ましたね。
https://jdk.java.net/14/
https://openjdk.java.net/projects/jdk/14/
早速 Pleiades Eclipse も Java 14 入りのバージョンが用意されました。
Pleiades Eclipse 2020-03 リリース 〜 Java 14 新機能を試そう!
余談ですが、おじさんは jdk14 って書かれると、jdk 1.4 を思い出しちゃいます。
さて、新機能は以下の通りです。次の記事から、順番に紹介していきたいと思います。
https://jdk.java.net/14/
https://openjdk.java.net/projects/jdk/14/
早速 Pleiades Eclipse も Java 14 入りのバージョンが用意されました。
Pleiades Eclipse 2020-03 リリース 〜 Java 14 新機能を試そう!
余談ですが、おじさんは jdk14 って書かれると、jdk 1.4 を思い出しちゃいます。
さて、新機能は以下の通りです。次の記事から、順番に紹介していきたいと思います。
2020/04/08
Java の final の仕様(3) - final フィールドのセマンティクスの有用性と仕組み
final フィールドのセマンティクス
final フィールドは初期化されたら変更されることはありません。そのため、final フィールドへのアクセスと、通常のフィールドへのアクセスは、その意味するところ (セマンティクス) が少し異なってきます。例えば、通常のフィールドの内容の参照は、「そのタイミングでの値」を取得するという意味を持ちますが、final フィールドの場合は内容が変わりませんから、「そのタイミングでの」という意味は抜け落ちます。Java は final フィールドのセマンティクスを活用して、メモリアクセスの最適化をしたり、同期化を減らしたり、セキュリティを担保したりしています。Java 言語仕様に沿って確認してみたいと思います。
2020/04/07
Java の final の仕様(1) - final 変数
Java の final の仕様について検索している方が多いように見受けられます。final キーワードは、変数、クラス、フィールド、メソッドの宣言に付加できますが、どういう意味になるかは簡単なようで意外にややこしいものです。Java 言語仕様に基づいてきっちり理解しておきましょう。
まず、final 変数について見ていきたいと思います。final クラス/メソッドについては次の記事をご覧ください。
まず、final 変数について見ていきたいと思います。final クラス/メソッドについては次の記事をご覧ください。
登録:
投稿
(
Atom
)