Jibで満足できず軽量なコンテナを求めてjlinkで遊ぼうと思ったら引っかかった。
調べてみたらすぐにlibjvm.so
が圧倒的に肥大化していることがわかった。でもなぜ?
openjdk jlink sizeとかでググってみると、色々と出ます。
https://matsumana.info/blog/2018/10/13/openjdk11-docker/
https://qiita.com/h-r-k-matsumoto/items/294eeb838cfd062d75b6
大体は以下のIssueのdebian系のopenjdkパッケージのjlinkにて、デバッグ用シンボルが含まれるという事例に至っているようです。
今回はRHEL系(CentOS 7)で起きてたのですが、多分これと同じ事が起きている気がします。
同じopenjdkでもalpine版なら回避できる等の事例をみると、openjdkが悪いというわけでもなさそうです。
そんな感じで詳しい原因は良くわかってないですが、再現させる手順とワークアラウンドを書いときます。
(パッケージのアップデートで挙動は変わるかもしれない。)
再現手順(2/21 時点)
今回実行する環境
$ cat /etc/redhat-release
Fedora release 28 (Twenty Eight)
今回は書いていませんが、CentOS 7のyumリポジトリにあるopenjdk 11でも確認しています。
yumリポジトリからインストールして試す
$ sudo dnf install java-9-openjdk-jmods.x86_64 java-11-openjdk-jmods.x86_64
$ export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.2.7-0.fc28.x86_64
$ JAVA_HOME/bin/jlink --compress 2 --module-path "$JAVA_HOME/jmods" --add-modules java.base --output "jre-$(basename $JAVA_HOME)"
$ export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.2.7-0.fc28.x86_64
$ JAVA_HOME/bin/jlink --compress 2 --module-path "$JAVA_HOME/jmods" --add-modules java.base --output "jre-$(basename $JAVA_HOME)"
$ du -hs jre-java-*
613M jre-java-11-openjdk-11.0.2.7-0.fc28.x86_64
407M jre-java-9-openjdk-9.0.4.11-6.fc28.x86_64
$ ls -l jre-*/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 624872128 2月 21 03:48 jre-java-11-openjdk-11.0.2.7-0.fc28.x86_64/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 410593824 2月 21 03:47 jre-java-9-openjdk-9.0.4.11-6.fc28.x86_64/lib/server/libjvm.so
ワークアラウンド: jdk.java.netで配布しているOpenJDKバイナリを使う
せっかくなんで9~12まで全部試した。
$ curl -LO https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz
$ curl -LO https://download.java.net/java/GA/jdk12/32/GPL/openjdk-12_linux-x64_bin.tar.gz
$ curl -LO https://download.java.net/java/GA/jdk9/9.0.4/binaries/openjdk-9.0.4_linux-x64_bin.tar.gz
$ curl -LO https://download.java.net/java/GA/jdk10/10.0.2/19aef61b38124481863b1413dce1855f/13/openjdk-10.0.2_linux-x64_bin.tar.gz
$ tar xzf openjdk-9.0.4_linux-x64_bin.tar.gz
$ tar xzf openjdk-10.0.2_linux-x64_bin.tar.gz
$ tar xzf openjdk-11.0.2_linux-x64_bin.tar.gz
$ tar xzf openjdk-12_linux-x64_bin.tar.gz
$ for dirpath in jdk-9.0.4 jdk-10.0.2 jdk-11.0.2 jdk-12; do
> export JAVA_HOME=$PWD/$dirpath
> $JAVA_HOME/bin/jlink --compress 2 --module-path "$JAVA_HOME/jmods" --add-modules java.base --output "jre-$(basename $JAVA_HOME)"
> done
$ du -hs jre-jdk-*
33M jre-jdk-10.0.2
35M jre-jdk-11.0.2
36M jre-jdk-12
32M jre-jdk-9.0.4
$ ls -l jre-*/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 624872128 2月 21 03:48 jre-java-11-openjdk-11.0.2.7-0.fc28.x86_64/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 410593824 2月 21 03:47 jre-java-9-openjdk-9.0.4.11-6.fc28.x86_64/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 21405080 2月 21 04:12 jre-jdk-10.0.2/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 22812128 2月 21 04:12 jre-jdk-11.0.2/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 23027240 2月 21 04:12 jre-jdk-12/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 20352536 2月 21 04:12 jre-jdk-9.0.4/lib/server/libjvm.so
起きないようです。サイズが1ケタ違う。これを求めてた。
(動作未確認)ワークアラウンド: strip -p --strip-unneeded
この方法で動くかどうかは確認していません
こちらの情報を見てためしました。
https://github.com/docker-library/openjdk/issues/217#issuecomment-430380403
stripで実行に影響がないシンボルを削るだけです。
$ strip -p --strip-unneeded jre-java-11-openjdk-11.0.2.7-0.fc28.x86_64/lib/server/libjvm.so
$ strip -p --strip-unneeded jre-java-9-openjdk-9.0.4.11-6.fc28.x86_64/lib/server/libjvm.so
$ ls -l jre-*/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 20025552 2月 21 03:48 jre-java-11-openjdk-11.0.2.7-0.fc28.x86_64/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 16928088 2月 21 03:47 jre-java-9-openjdk-9.0.4.11-6.fc28.x86_64/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 21405080 2月 21 04:12 jre-jdk-10.0.2/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 22812128 2月 21 04:12 jre-jdk-11.0.2/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 23027240 2月 21 04:12 jre-jdk-12/lib/server/libjvm.so
-rw-rw-r--. 1 fukasawah fukasawah 20352536 2月 21 04:12 jre-jdk-9.0.4/lib/server/libjvm.so
問題のlibjvm.soに対して行うとサイズ的には問題が解消できている事が分かります。むしろ小さい。
ただ、これをやったあとnm
コマンドを見るとシンボルが全く見つからなくなるので、gdb等をつかったJVMより下のレベルのデバッグが困難になるはず。(一方、jdk.java.netのほうは残っているのでgdb等は使えるはず)