- 深入解析Java虛擬機(jī)HotSpot
- 楊易
- 1701字
- 2021-01-07 11:18:26
1.5 Graal VM
如果說(shuō)HotSpot VM代表了傳統(tǒng)的Java保守陣營(yíng),那么Graal VM無(wú)疑是Java改革陣營(yíng)的代表。
大部分腳本語(yǔ)言或者有動(dòng)態(tài)特性的語(yǔ)言(比如CPython、Lua、Erlang、Java、Ruby、R、JS、PHP、Perl、APL等)都需要用到一個(gè)語(yǔ)言虛擬機(jī),但是這些語(yǔ)言的虛擬機(jī)實(shí)現(xiàn)差別很大,比如CPython/PHP的虛擬機(jī)性能相對(duì)較差,Java的HotSpot VM、C#的CLR和JS的v8卻是業(yè)界頂尖級(jí)別。那么,能不能付出較小努力,用一個(gè)業(yè)界頂尖級(jí)別的虛擬機(jī)來(lái)運(yùn)行這些語(yǔ)言,享受該虛擬機(jī)的一些工匠特性,如GC、鎖優(yōu)化、JIT編譯器呢?
答案是肯定的。首先,對(duì)于Java、Scala、Groovy這些本來(lái)就是基于JVM的語(yǔ)言,通過(guò)編譯器前端工具得到Java字節(jié)碼后直接在JVM上運(yùn)行即可。對(duì)于CPython、R、Ruby、PHP、Perl乃至自己寫(xiě)的一門新的語(yǔ)言,其開(kāi)發(fā)流程一般分為如下4個(gè)階段:
1)首先解析源代碼到AST(Abstract Syntax Tree,抽象語(yǔ)法樹(shù)),寫(xiě)一個(gè)AST解釋器。
2)當(dāng)有人使用這門語(yǔ)言時(shí),語(yǔ)言設(shè)計(jì)者可以繼續(xù)迭代,實(shí)現(xiàn)一個(gè)完整的語(yǔ)言虛擬機(jī),包括GC、運(yùn)行時(shí)等,代碼的執(zhí)行仍然使用AST解釋器。
3)用的人多了,語(yǔ)言繼續(xù)迭代,將AST轉(zhuǎn)換為字節(jié)碼,代碼執(zhí)行使用字節(jié)碼解釋器。
4)用的人特別多,性能也很關(guān)鍵,如果這個(gè)語(yǔ)言社區(qū)有足夠的資金和人力,那么可以寫(xiě)JIT編譯器,提升GC性能等,不過(guò)大部分語(yǔ)言都到不了這一步。
一門語(yǔ)言至少要達(dá)到階段3才算基本滿足工業(yè)生產(chǎn)的要求,但是人們希望一門語(yǔ)言在階段1時(shí)性能就足夠好,而不用花那么多精力和財(cái)力達(dá)到階段3甚至階段4,這就是Truffle語(yǔ)言實(shí)現(xiàn)框架出現(xiàn)的原因。Truffle是一個(gè)Java框架,自然運(yùn)行在JVM上。在這個(gè)框架下,用戶只需要實(shí)現(xiàn)具體語(yǔ)言的AST解釋器,付出的努力比較小,性能也足夠好。因?yàn)門ruffle框架可以使AST在解釋過(guò)程中根據(jù)節(jié)點(diǎn)的類型反饋信息對(duì)節(jié)點(diǎn)進(jìn)行變形,也可以在AST解釋過(guò)程中進(jìn)行部分求值(Partial Evaluation)[1],將這個(gè)AST的一部分節(jié)點(diǎn)編譯為機(jī)器代碼,不用解釋執(zhí)行AST節(jié)點(diǎn),即可直接執(zhí)行。
Truffle將AST節(jié)點(diǎn)編譯為機(jī)器代碼使用的編譯器是Graal,這是一個(gè)用Java編寫(xiě)的即時(shí)編譯器。前面提到,Truffle是一個(gè)Java框架,那么一個(gè)用Java語(yǔ)言編寫(xiě)的即時(shí)編譯器要如何編譯Java代碼呢?答案是通過(guò)JEP 243的JVMCI。JVM是用C++語(yǔ)言編寫(xiě)的,在JVM中內(nèi)置了兩個(gè)用C++編寫(xiě)的即時(shí)編譯器,C1和C2。一般頻繁的代碼先用C1編譯,這些代碼即熱點(diǎn),如果熱點(diǎn)繼續(xù),則使用C2編譯。JVMCI相當(dāng)于把本該交給C2編譯的代碼交給Graal編譯,然后使用編譯后的代碼。用Java寫(xiě)即時(shí)編譯器看起來(lái)很神奇,其實(shí)很正常,因?yàn)榧磿r(shí)編譯說(shuō)到底就是將一段byte[]代碼在運(yùn)行時(shí)轉(zhuǎn)換為另一段byte[]代碼,可以用任何語(yǔ)言實(shí)現(xiàn),只是實(shí)現(xiàn)過(guò)程中的難易程度不同。
到目前為止,Java、Scala、Groovy已經(jīng)可以在JVM上運(yùn)行了,CPython、R、Ruby、JS通過(guò)Truffle框架實(shí)現(xiàn)一個(gè)AST解釋器后也可以在JVM上運(yùn)行。那么如何處理如C/C++、Go、Fortran這類靜態(tài)語(yǔ)言呢?對(duì)于這個(gè)問(wèn)題,Graal VM給出的解決方案是Sulong框架。用戶用一些工具(如clang)將C/C++這類語(yǔ)言轉(zhuǎn)換為L(zhǎng)LVM IR,然后使用基于Truffle的AST解釋器解釋LLVM IR。這里基于Truffle的AST解釋器就是Sulong,如圖1-6所示。
現(xiàn)在絕大部分語(yǔ)言都可以在JVM上運(yùn)行了,將上面提到的所有技術(shù)放到一起,這個(gè)整體就叫作Graal VM。Graal VM就像皇帝的新衣,人人都在討論,但是如果要回答它到底是什么卻言之無(wú)物。實(shí)際上Graal VM這個(gè)語(yǔ)言虛擬機(jī)并不是真正存在的,Graal VM是指以Java虛擬機(jī)為基礎(chǔ),以Graal編譯器為核心,以能運(yùn)行多種語(yǔ)言為目標(biāo),包含一系列框架和技術(shù)的大雜燴,如圖1-7所示。
但這并不是Graal VM的全部。圖1-7中的所有語(yǔ)言最終都運(yùn)行在JVM上,需要運(yùn)行機(jī)器提前安裝JDK環(huán)境。JVM由于自身原因,啟動(dòng)速度比較慢,內(nèi)存負(fù)載較高。那么,能不能把程序直接打包成平臺(tái)相關(guān)的可執(zhí)行文件,后面直接執(zhí)行這個(gè)可執(zhí)行文件,而不依賴JVM呢?
交出這份答卷的是Substrate VM。Substrate VM借助Graal編譯器,可以將Java程序AOT編譯為可執(zhí)行程序。它首先通過(guò)靜態(tài)分析找到Java程序用到的所有類、方法和字段以及一個(gè)非常小的SVM運(yùn)行時(shí),然后對(duì)這些代碼進(jìn)行AOT編譯,生成一個(gè)可執(zhí)行文件。
Substrate VM的想法很美好,但是在實(shí)踐中會(huì)遇到諸多問(wèn)題,因?yàn)镴ava有反射等動(dòng)態(tài)特性,這些特性可能導(dǎo)致新類加載無(wú)法通過(guò)靜態(tài)分析解決。目前Substrate VM的GC是一個(gè)比較簡(jiǎn)單的分代GC,缺少很多調(diào)試工具和性能分析支持,編譯速度較慢,不過(guò)這些都在慢慢完善,生產(chǎn)環(huán)境上也有阿里巴巴和Twitter等公司在不斷嘗試Substrate VM的實(shí)際落地,并取得了顯著的效果。
[1] 區(qū)別于函數(shù)式編程中的部分應(yīng)用(Partial Application)和柯里化(Currying)概念。
- WildFly:New Features
- 基于粒計(jì)算模型的圖像處理
- PHP 編程從入門到實(shí)踐
- Mastering Ext JS
- Expert Data Visualization
- Express Web Application Development
- Multithreading in C# 5.0 Cookbook
- Python圖形化編程(微課版)
- 從零開(kāi)始:UI圖標(biāo)設(shè)計(jì)與制作(第3版)
- 自學(xué)Python:編程基礎(chǔ)、科學(xué)計(jì)算及數(shù)據(jù)分析(第2版)
- Java 從入門到項(xiàng)目實(shí)踐(超值版)
- Building Business Websites with Squarespace 7(Second Edition)
- PowerDesigner 16 從入門到精通
- Android智能手機(jī)APP界面設(shè)計(jì)實(shí)戰(zhàn)教程
- Java設(shè)計(jì)模式深入研究