GraalVM到底是何方神聖?

語言: CN / TW / HK

JVM的弊端

JVM實現了跨平台,使得一次編譯即可到處運行,但是詹姆斯·高斯林沒有跟你説的是,應用運行之前要先啟動JVM虛擬機,然後還要加載一大批的類、並做鏈接和初始化等步驟,而使得光啟動一個JVM就得花一大把時間,JVM啟動完之後才能執行應用程序本身的啟動工作,比如啟動Spring容器、啟動Tomcat等等。

在一些場景下,集羣需要做動態擴縮容,這個動作當然是越快越好,不可能請求過來了,花了半天時間來啟動應用,等應用啟動完,客户端那邊都已經超時了。

特別像目前也比較火的FaaS,更加需要應用程序能快速的啟動。

GraalVM與Go

所以,近幾年來,Go語言火了,Go語言是一種編譯型語言,我們需要先把Go代碼直接編譯成為一個二進制執行文件,比如windows上的exe文件,然後直接運行exe文件就能快速啟動程序。

如果説,十年前,Spring是Java的春天,那現在GraalVM就是Java的救世主,Java要想不被Go擠掉,整個Java生態都要向GraalVM靠齊。

GraalVM提供了很多功能,其中一個功能就是能把Java代碼直接編譯成為二進制文件,比如exe文件,從而使得Java程序也能夠快速啟動。

GraalVM與Docker

目前,大部分Java應用應該都是運行在Docker容器中,這就需要Docker容器中也要安裝JDK或JRE,但是如果利用GraalVM將Java應用編譯成為了exe文件,那麼我們就可以直接把exe文件打成一個Docker鏡像了,從而不需要在Docker中按照JDK了,這樣將使得Docker容器更加小巧,也更加適應自動擴縮容。

GraalVM的缺點與未來

GraalVM為了把Java程序編譯為一個可執行的二進制文件,需要預先確定程序中用到的所有類,但是Java程序中很有可能某些類是動態生成的,比如很多框架中都用到了動態代理,從而程序運行過程中會動態生成一些類。

為了解決這個問題,比較笨的辦法是,通過配置文件指定哪些類是動態生成的,比較聰明的辦法是,先運行一下程序自動找到哪些類是動態生成的。

GraalVM這兩種辦法都是支持的,這樣對於Spring、SpringBoot這些框架就能省事很多了,

這樣,對於一個SpringBoot應用程序,就可以利用GraalVM將它編譯成為一個可執行的二進制文件了。

當然,Spring及SpringBoot為了進一步提升啟動速度,Spring及SpringBoot自身也做了一些優化,比如Spring AOT將Bean掃描轉移到了編譯期來做,從而能進一步提升啟動速度。

後續

今天,簡單聊聊GraalVM,後續會出GraalVM的實戰教程,以及Spring AOT的底層實現原理,希望大家能點贊、分享、在看。

公眾號:Hoeller