GraalVM下一代JVM到底是什么?
本文轉載自微信公眾號「咖啡拿鐵」,作者咖啡拿鐵。轉載本文請聯系咖啡拿鐵公眾號。
背景
上周有幸去QCON聽了一下各個公司大佬的技術分享,但是至于收獲嘛,知識沒帶走多少,帶走了不少展臺送的小禮品,哈哈~。圖片
其實挺這種大會想要真正的了解細節還是難,主要還是了解行業新趨勢,技術新動態,其中阿里有個冷啟動加載技術的分享,提到了一個技術叫GraalVM,這個單詞之前或多或少不經意間看見過,但是一直沒有了解過,正好這位阿里的大佬再次提及這次技術,沒想到這個技術如此強大,于是下來便細細的查閱了一些資料,想和大家分享一下。
GraalVM是什么?
再說GraalVM之前,我們先來聊聊JVM,JVM也就是我們的java虛擬機,如果我們想要運行Java程序,那就需要在JVM上進行運行,通過Jvm將我們的代碼翻譯成機器能理解的代碼,然后執行。那么我們JVM是只能運行java的嘛,當然不是,我們還有很多比較出名的語言比如,Scala,Groovy都是通過各自的編譯器編譯成java虛擬機對應的字節碼,然后來進行執行。
再來回到GraalVM,乍一看好像是Graal這個語言的虛擬機,其實不是的,GraalVM是ORACLE開發的一款“通用”虛擬機,怎么理解這個通用呢?上面我們說到JVM可以支持除了Java以外的語言,那么GraalVM他是可以支持JavaScript,Python,Ruby,C和C ++以及JVM語言等等(理論上來說只要做對應語言的開發,所有語言都可以支持)。
但是這里要值得注意的是GraalVM是用java寫的,所以作為一個JAVA程序員如果想修改虛擬機的代碼,是不需要理解C++或者C等語言的。
GraalVM作用是什么?
啟動加速
在QCon上還有一些技術聽得比較多,那就是k8s,serverless等等,我們知道彈性擴展是其中的核心,比如當我們的集群出現突發流量的時候,一般這個時候會快速擴容機器,但是由于我們的Java的特性,帶來兩個方面的慢:
- 啟動慢:當我們啟動JAVA的時候,也就是將我們的class文件加載到jvm中,這個加載class可是一筆不小開銷,需要檢索,驗證,解析等等。
- 啟動后開始運行慢:我們知道java代碼在啟動后的一段時間之內是解釋執行的,如果想要達到編譯執行,是需要借助我們的JIT技術,將其直接編譯成機器碼執行,從而達到高效執行,這個也就是我們所說的預熱。
從QCon上截取了一張圖,也就是我們java編譯技術演進。
前面兩個階段也就是大家平常比較熟悉的階段,通過翻譯和c1編譯和c2編譯來進行代碼執行,而第三部分出現了一個AOT技術,也就是靜態編譯,可以在執行代碼之前就將我們的代碼編譯成機器碼,和C++一樣,但是由于JAVA有很多動態特性,一般我們利用jaotc來對jdk自帶的包進行靜態編譯,然后其他的包依然采用翻譯和jit執行。
所以就迎來了第四階段SubstrateVM(后面簡稱SVM),這個是基于Graal的AOT框架,他可以將我們的動態特性也可以進行靜態編譯,可以想一下Java里面最動態的其實就是反射,比如你要執行某個類的方法,你可能會這么寫:
- String method = "xx";
- object.invoke(method);
可以發現我們的方法其實是一個字符串并且還是一個動態的變量,那這種這么動態的東西如何做到靜態編譯了,阿里內部是通過觀察,比如這個程序上去跑個幾周,獲取invoke的所有場景,然后一起進行編譯,當時也提問到如果這個有沒有觀察的怎么辦呢,那么這個的確就會報錯,所以這一塊的使用的確是個問題。
通過靜態編譯完成之后,我們的性能有得到提升嗎?
從上面的性能數據來看,我們的性能和Go是相當的,內存只有Go的一半,怪不得他們都在說Graal就是用來替代go的。
同時Graal編譯器也可以替代C2編譯器,在twitter和facebook內部生產環境已經使用Graal進行替換C2。
所以對彈性伸縮,啟動速度要求比較高的程序,可以考慮將GraalVM作為自己的虛擬機選擇。
多語言調用
上面說過我們GraalVM支持很多語言,設想一下我們有個這樣的需求,java做服務器的開發,python或者R語言去做數據分析,以前我們可能需要調用Rpc去做這樣的事,現在我們可以將他們放在同一個項目或者同一個文件當中,利用GraalVM的特性就可以做到這樣的事
總結
GraalVM的確是一個比較新的技術,他的整個野心也看得出來是非常大的,畢竟想做的是一個通用的虛擬機,如果他做起來的話,對Java程序員是比較好的,因為這個是用Java進行開發的,大家其實有興趣可以下來在搜索一些資料再了解一下。