最近、JDKの話題をTLで見ることが増えましたね。

どれを使えばよいのかは人それぞれだと思いますが、以下をひと通り読むと良さそうです。

JDK: 新しいリリースモデル解説 (ver. 2.2) @ 札幌 - 20190209 from オラクルエンジニア通信

ところで、Oracle Code Tokyo 2019で@yamadamnさんのセッションがあるみたいですよ。



ここからがこの記事の本題です。

そういえば、CentOSでもOpenJDK 11がyumでインストール出来るなーという事を思い出し、
Red HadのOpenJDK 11と何が違うのか気になったので調べてみました。


まず、Twitterで「openjdk centos」というキーワードで検索すると以下が見つかります。

なるほどなるほど。

CentOSのOpenJDK 11のrpmソースはここですね。
https://git.centos.org/rpms/java-11-openjdk/commits/c7

コミットを見てみると、java-11-openjdk-11.0.2.7-0.el7_6 と、
java-11-openjdk-11.0.3.7-0.el7_6の差分はこの1つだけでした。
https://git.centos.org/rpms/java-11-openjdk/c/d00a18099714d5f49ee7fb611210853246445912?branch=c7

更に、Filesディレクトリとspecファイルのchangelogを見てみると、
ソースファイルはshenandoah-jdk11-shenandoah-jdk-11.0.3+7.tar.xzを使い、
Upstream(shenandoah-jdk11)にマージされていないパッチはこのディレクトリで管理・適用されているようです。


CentOSのrpmソースを見ても、shenandoah-jdk11-shenandoah-jdk-11.0.3+7.tar.xzをどこからダウンロードしてるのかわからなかったのですが、Fedoraの方を見るとOpenJDKのshenandoah/jdk11みたいですね。


誰がメンテしてくれてるのかなと思って、specファイルのchangelogを見てみると、CentOSもFedoraもRed Hatの人達が2〜3人でメンテしてくれているようです。


ちなみに、Shenandoahっていうのは、Red Hatが開発している新しいGCアルゴリズムです。
JDK 12から入ってます。

上記Shenandoah GCのwikiを見ると、Backports to JDK 8u and JDK 11u are available as wellって書いてるので、ちょっと確認してみましょう。

$ docker container run --rm -it centos:7.6.1810 bash
[root@a860c23cf664 /]# yum install -y java-11-openjdk-devel
[root@a860c23cf664 /]# java -version
openjdk version "11.0.3" 2019-04-16 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.3+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.3+7-LTS, mixed mode, sharing)
[root@a860c23cf664 /]# java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
     bool UseAdaptiveSizePolicyWithSystemGC = false      {product} {default}
     bool UseConcMarkSweepGC                = false      {product} {default}
     bool UseEpsilonGC                      = false {experimental} {default}
     bool UseG1GC                           = true       {product} {ergonomic}
     bool UseMaximumCompactionOnSystemGC    = true       {product} {default}
     bool UseParallelGC                     = false      {product} {default}
     bool UseParallelOldGC                  = false      {product} {default}
     bool UseSerialGC                       = false      {product} {default}
     bool UseShenandoahGC                   = false      {product} {default}
     bool UseZGC                            = false {experimental} {default}

UseShenandoahGCっていうJVMオプションがあるので、OpenJDK 11でShenandoah GC使えるみたいですね。
そして、experimentalじゃなくてproductになってる・・・?


OpenJDK 8でも試してみましょう。

$ docker container run --rm -it centos:7.6.1810 bash
[root@0e0f3ad821d8 /]# yum install -y java-1.8.0-openjdk-devel
[root@0e0f3ad821d8 /]# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
[root@0e0f3ad821d8 /]# java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
     bool UseAdaptiveSizePolicyWithSystemGC  = false {product}
     bool UseConcMarkSweepGC                 = false {product}
     bool UseG1GC                            = false {product}
     bool UseMaximumCompactionOnSystemGC     = true  {product}
     bool UseParNewGC                        = false {product}
     bool UseParallelGC                     := true  {product}
     bool UseParallelOldGC                   = true  {product}
     bool UseSerialGC                        = false {product}
     bool UseShenandoahGC                    = false {product}

OpenJDK 8でもShenandoah GC使えるみたいです。こちらもproduct。


ついでなので、Red HatのOpenJDK 11も確認しておきます。
(AWSのEC2を使いました)

rpmソースが見つからなかった(サブスクリプション契約があれば見れる?)ので、ソースファイルがどれかわかりませんでしたが、 きっとOpenJDKのshenandoah/jdk11だと思うので、ビルド番号とShenandoahが含まれているかどうか程度の確認をします。

[ec2-user@ip-xx-xx-xx-xx ~]$ sudo yum install -y java-11-openjdk-devel
[ec2-user@ip-xx-xx-xx-xx ~]$ java -version
openjdk version "11.0.3" 2019-04-16 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.3+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.3+7-LTS, mixed mode, sharing)
[ec2-user@ip-xx-xx-xx-xx ~]$ java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
     bool UseAdaptiveSizePolicyWithSystemGC = false      {product} {default}
     bool UseConcMarkSweepGC                = false      {product} {default}
     bool UseEpsilonGC                      = false {experimental} {default}
     bool UseG1GC                           = true       {product} {ergonomic}
     bool UseMaximumCompactionOnSystemGC    = true       {product} {default}
     bool UseParallelGC                     = false      {product} {default}
     bool UseParallelOldGC                  = false      {product} {default}
     bool UseSerialGC                       = false      {product} {default}
     bool UseShenandoahGC                   = false      {product} {default}
     bool UseZGC                            = false {experimental} {default}

ビルド番号がCentOSと同じbuild 11.0.3+7-LTSで、Shenandoahも含まれています。

OpenJDK 8も確認してみます。

[ec2-user@ip-xx-xx-xx-xx ~]$ sudo yum install -y java-1.8.0-openjdk-devel
[ec2-user@ip-xx-xx-xx-xx ~]$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
[ec2-user@ip-xx-xx-xx-xx ~]$ java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
     bool UseAdaptiveSizePolicyWithSystemGC  = false {product}
     bool UseConcMarkSweepGC                 = false {product}
     bool UseG1GC                            = false {product}
     bool UseMaximumCompactionOnSystemGC     = true  {product}
     bool UseParNewGC                        = false {product}
     bool UseParallelGC                     := true  {product}
     bool UseParallelOldGC                   = true  {product}
     bool UseSerialGC                        = false {product}
     bool UseShenandoahGC                    = false {product}

こちらもビルド番号がCentOSと同じbuild 1.8.0_212-b04で、Shenandoahも含まれています。



まとめ

  • CentOSとFedoraのOpenJDK 11は、OpenJDKのshenandoah/jdk11をベースにUpstreamにマージされていないパッチを当てているっぽい
  • CentOS独自のパッチが当たっているのかは、rpmソースをぱっと見てもわからなかった。Red Hatのrpmソースと比べたらわかるのかも
  • Red HatとCentOSでコンパイルオプションなどに違いがあるのかはrpmソースをぱっと見てもわからなかった。Red Hatのrpmソースと比べたらわかるのかも
  • ビルド番号とShenandoah有無から見ると、Red HatとCentOSは同じOpenJDKのshenandoah/jdk11をベースにしている気がする
  • Red HatのOpenJDKにできるだけ近いものを無償で使いたい場合(Red HatのOpenJDKは無償ではありません)、CentOSのOpenJDKは選択肢の1つになりそう

あと、僕はまだ試してないですが、ojdkbuildっていうやつもあるみたいです。
ojdkbuildとCentOS OpenJDKの立ち位置の違いが気になるところです。