Spring Boot の容量を減らしてみた

More than 1 year has passed since last update.


自己紹介


  • opengl-8080

  • 主に Qiita で技術メモを書いたり

  • 関西の SIer 勤務



Spring Boot とは


  • Spring ベースのアプリケーションを簡単に作れるようにした仕組み・フレームワーク

  • ビルド結果が単一の jar ファイルにまとめられる



単一 jar のメリット


  • AP サーバーが同梱されているので、環境ごとに AP サーバーを用意する必要がない


  • java -jar で起動できる楽さ

spring-boot.JPG



単一 jar のデメリット


  • AP サーバーも含め全ての依存ライブラリを内包するため、ファイルサイズが大きくなる

spring-boot.JPG



jar サイズをがんばって減らしてみた



結果

img1.JPG



結果

img2.JPG



サイズ比較

graph_2.JPG



どうやったのか?



Java で Hello World はどうやりますか?



1.コードを書く


Hello.java

public class Hello {

public static void main(String... args) {
System.out.println("Hello World");
}
}



2.javac でコンパイル

$ javac Hello.java



3.Hello.class が生成される

after-javac.jpg



4.java で実行

$ java Hello

Hello World



おわかりいただけただろうか?




コンパイル前のソースコードの方が容量が小さい!



javacを叩けるAPIは標準である!

java-compiler.jpg

https://docs.oracle.com/javase/jp/8/docs/api/javax/tools/JavaCompiler.html


yaruo.jpg



改良版 jar の仕組み

|-LightweightJarExecutor.class  :

| → 自分自身の jar の中からソースを取り出してコンパイル・実行するコード
|-...
`-src/ : Spring Boot および依存するライブラリのソース一式
|-ch/ : logback
|-com/ : jackson とか com.sun とか
|-javax/ : javaee の標準 API
|-META-INF/
|-org/ : Spring, hibernate, JBoss, Tomcat, etc...
`-sample/ : Spring MVC の Hello World


起動時の動作


  1. 自分自身の jar の中からソースコードを抽出し、一時ディレクトリにコピーする

  2. 一時ディレクトリに出力したソースを JavaCompiler を使ってコンパイルする

  3. コンパイル結果の出力先から URLClassLoader を使って Spring Boot のメインクラス(JarLauncher)をロードする


  4. JarLaunchermain() メソッドを実行する



まさに Just In Time Compile!(違う)



そのままだと無駄が多く軽量化できない

lightweight-jar.jpg



無駄1:コメント

lightweight-jar.jpg



無駄2:アノテーション

lightweight-jar.jpg



無駄3:private

lightweight-jar.jpg



無駄4:空白+改行

lightweight-jar.jpg



無駄に洗練された無駄のないコード

lightweight-jar.jpg



結果 5MB の容量削減に成功!:grin::thumbsup:

graph_2.JPG



代償1:起動が遅い :innocent::thumbsdown:

lightweight-jar.jpg



代償2:デバッグ不可能 :joy::thumbsdown:

lightweight-jar.jpg



良い子はマネしないでください