openjdkのjlinkで異様に大きなランタイムができあがる問題と回避策

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にて、デバッグ用シンボルが含まれるという事例に至っているようです。

https://github.com/docker-library/openjdk/issues/217

今回は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等は使えるはず）