Oracle釋出多語種虛擬機器平臺GraalVM 1.0

weixin_34253539發表於2018-05-06
\

看新聞很累?看技術新聞更累?試試下載InfoQ手機客戶端,每天上下班路上聽新聞,有趣還有料!

\
\\

Oracle釋出了多語種虛擬機器平臺GraalVM的1.0版本。初始釋出版包括執行Java和JVM語言(通過位元組碼)的能力,對JavaScript和Node.JS的全面支援,以及對Ruby、Python、R語言和LLVM位元組碼的測試性支援。

\\

整個平臺包含多個元件:

\\
  • Graal:一個由Java語言編寫的JIT編譯器。\\t
  • SubstrateVM:一個對執行容器抽象層的輕量級封裝。\\t
  • Truffle:一個用於構建語言解析器的工具集和API。\

整個平臺的目的是提供一個可以嵌入到另一個執行容器中的多語言執行環境,不論這個執行容器是OpenJDK容器還是諸如Oracle或者MySQL資料庫之類的均可。

\\

InfoQ與Oracle實驗室研究總監Thomas Wuerthinger就GraalVM進行了深入訪談。

\\

InfoQ:您能介紹一下GraalVM的歷史嗎?它哪裡

\\
\

Thomas Wuerthinger:這個專案最初的想法是編譯器不應該對程式語言語義有特殊支援。究其原因是Oracle內部對包括JavaScript、R和Ruby在內的多種程式語言都有所涉獵。

\\

我們覺得以下兩個核心領域可以通過研究進行突破:

\\
  • 軟體行業的虛擬機器架構師普遍認為,如果想獲得最優的效能,某種語言的虛擬機器需要結合該語言的語義針對性設計。\\t
  • 從Java7開始,通過在JVM規範中增加invokedynamic位元組碼指令,Java架構支援了多種語言。GraalVM團隊覺得由於Java位元組碼已經內建了太多Java語義,100%的相容實現長期來看會有更好的效能。\

同時我們還有一個目標是構建一個有競爭力的完備的多語言引擎,因此我們開始和一些大學開始合作開展支援其他語言的工作。

\\

普渡大學的一個團隊做了R語言的一個實現,加州大學歐文分校的一個團隊在2012年到2014年完成了Python語言的一個實現。一個實習生將Ruby語言實現作為他的論文專案,它有很多新奇有趣的特性,我們認為它很好地證明了我們的多語言編譯器是完全通用的。隨後,我們將這些語言的專案帶到了Oracle實驗室以為這些語言編寫工業質量的實現。

\\

隨著GraalVM 1.0的釋出,我們認為我們已經證明了擁有高效能的多語言虛擬機器是可能的,並且實現這個目標的最佳方式不是通過類似Java和微軟CLR那樣帶有語言特性的位元組碼。

\
\\

InfoQ:組成GraalVM的核心技術是什麼?這些技術將如何幫助開發人員?

\\
\

Wuerthinger:GraalVM的核心技術稱為“部分評估”,它是一項將直譯器自動轉換成編譯器的技術。語言開發者能夠僅僅專注於構建一個抽象語法樹(Abstract Syntax Tree,AST)直譯器,而無需編寫程式碼生成器和其他諸如垃圾回收器等低階執行時功能。

\\

我們內建於GraalVM的一項核心技術是邏輯/物理資料分離。這使得任何記憶體資料佈局都能夠表現為一個本地語言物件。大部分虛擬機器對於物件都有一個特定的佈局(物件頭通常稱為“盒子”),因此為了獲取物件在程式語言中的語義,物件記憶體結構必須有相同的佈局。

\\

這意味著在大部分虛擬機器中,使用者必須為一個“物件”分配記憶體和複製資料。

\\

在Graal中,不同語言互操作可以實現零開銷,因為JavaScript物件表現的行為可以是JavaScript物件,也可以是R物件,而無需額外的物件建立和資料複製。

\\

該特性也允許例如以特定二進位制格式暴露高階語言物件資料,而無需實際建立這些高階語言物件。

\\

另一項核心技術是LLVM直譯器。我們實現了一個針對LLVM位元組碼的GraalVM直譯器,該位元組碼是LLVM編譯器的輸出,因此可以完美支援生成原生二進位制可執行檔案的語言(例如C++、FORTRAN、Rust等等)。

\\

實現語言支援的一個主要問題是,這些語言通常有使用本地位元組碼實現的庫檔案(通常是C/C++),並且它們會使用暴露語言內部的API。因此如果希望相容一個語言系統,我們必須支援本地庫。

\\

像JRuby和Nashorn那樣的實現方式其中一個問題就是,它們無法支援包含本地庫的模組,這會導致相容性問題。

\\

GraalVM最後增加的獨立模組稱為SubstrateVM。它的做法是將虛擬機器在混合和匹配的基礎上變得可嵌入。類似Java Hotspot這樣的常規語言虛擬機器期望能夠控制所有東西:哪個執行緒能夠被排程,記憶體分配器如何工作,訪問作業系統等等。

\\

因此,我們需要一種允許底層系統提供這些服務的技術層,而SubstrateVM通過支援動態JIT編譯器(如垃圾回收器)所需要的內容來彌補這一缺失。例如,當我們執行在一個資料庫中時,資料庫希望能夠控制記憶體管理、執行緒分配等。

\\

SubstrateVM是一個“極薄”的虛擬機器,能夠嵌入到類似資料庫這樣的系統中。因此如果使用者需要在資料庫中執行Graal編譯器,資料庫可以指定最大堆記憶體和不是通過Java虛擬機器機制,通知資料庫可以管理程式碼構件而不是JVM類載入器。

\\

SubstrateVM實現這一功能的最重要方式是像Graal一樣對Java程式碼進行提前編譯(ahead-of-time compilation)而成為本地二進位制程式碼,當然需要假設所有依賴自包含封閉世界假定(closed world assumption)(所有需要使用的類在編譯期都需要明確)。因此,當使用者將Graal編譯器部署到資料庫的時候,需要使用Graal將GraalVM語言編譯成本地共享庫,並且它們不必在執行時編譯。

\
\\

InfoQ:什麼是Truffle?為什麼需要它?

\\
\

Wuerthinger:Truffle是構建一個新的GraalVM語言時所依賴的GraalVM直譯器API。直譯器的工作首先是將原始碼解析成所謂的抽象語法樹(Abstract Syntax Tree,AST)。例如,如果我們的程式碼是:c = a + b,那麼AST將會包含2個節點,一個是加操作,它包括兩個子節點a和b,第二個節點是賦值操作,包含子節點c和加操作節點。

\\

直譯器內部實現,例如AST相關操作需要繼承Truffle介面,如果這樣做了Graal編譯器將會觀察語言直譯器活動以學習語言語義,因此可以生成針對這種語言的編譯器。

\
\\

InfoQ:GraalVM的最令人矚目的元件之一是Graal編譯器,它是一個名為“Graal”、基於Java的JIT編譯器。您能介紹一下Graal希望能夠改進當前的C2編譯器(目前OpenJDK中使用的由C++編寫的JIT編譯器)遇到的難點嗎?另外,Graal未來有希望替代C2稱為OpenJDK主線的預設編譯器嗎?

\\
\

Wuerthinger:Graal編譯器在Java 10中是一個實驗性的編譯器,Oracle對於它將來能夠成為預設編譯器是樂觀的。

\\

類似Graal這樣的編譯器最大的優勢是它首先編譯其自身(因為它由Java編寫),這使得可以直接在高階語言層面編寫Graal,而不用像C2那樣直接操作AST。舉例來說,對於Graal來說能夠更容易的進行積極內聯和物件逃逸分析,這使得程式能夠自動的移除更多的物件分配。總的來說,程式寫的約抽象,Graal編譯器能夠做的更多,因此我們會看見Graal對於Java 8或者Scala中支援的流(Stream)和Lambda等功能會有更大的效能提升。

\
\\

InfoQ:Oracle正在將GraalVM作為多語言虛擬機器進行大力推廣。其1.0版本釋出的內容和Java 10中包含的部分內容有什麼區別?對於類似JRuby開發者來說,應該選擇哪個?GraalVM應該被視作是一個獨立的專案,還是OpenJDK的一部分?未來Graal的釋出節奏會與Java釋出節奏保持一致,還是會獨立進行?

\\
\

Wuerthinger:GraalVM和Java是100%獨立的專案,它們都擁有大量的開源存在和獨立的釋出節奏,並且它們都同時從彼此專案中獲取各種技術。Java 10從GraalVM中獲取了編譯器(作為實驗性選擇),而GraalVM將Java 8作為其支援的語言之一。GraalVM支援許多語言,不僅僅是Java,因此我們也使用了來自Node.js、JRuby的技術,來自GNU R語言的實現等內容。

\\

和大多陣列織中的技術生產者/消費者關係類似,消費者會從其他提供者處等待新技術的成熟,然後使用它。類似的,Java平臺組織(Java Platform Group)在引入新技術的時候也是保守的,他們需要確認這項技術不會破壞現存的部署,以及一系列向下和向上相容性考慮,所以會有一些滯後。

\
\\

InfoQ:IBM實現的OpenJ9執行時環境使用了和GraalVM不同的實現方式。您能解釋一下您瞭解到的和OpenJ9/OMR主要區別是什麼,GraalVM有什麼獨到之處?

\\
\

Wuerthinger:OpenJ9試圖通過增加一些限制性的JIT編譯功能來加速已經存在的單一語言執行時環境(例如Ruby的MRI直譯器)。他們這種實現方式的優點是適配和相容已經存在的執行時環境比較方便。主要的劣勢是提升比較有限。

\\

首先,與在GraalVM上執行的Ruby數量級相比,他們的Ruby原型的效能優勢非常小。主要原因是GraalVM可以進行更多的分析和推測優化,而OMR保留了現有直譯器的資料結構。

\\

其次,他們需要開發者編寫一個程式碼生成器,並且無法通過部分評估自動從直譯器中得到編譯後的程式碼。

\\

第三,沒有內建的物理/邏輯資料分離。

\\

這點直接導致了最終到的第四點:通過他們的實現方式沒有能力實現高效的語言互操作性。

\\

OMR可以對類似Ruby MRI這樣尚未進行很好優化的現存單語言執行時提供微小的效能提升。GraalVM使用了完全不同的方式對這些語言有了數量級的改進,並且對於任何支援的語言有零開銷的互操作性。

\
\\

InfoQ:對於Graal更廣泛的社群參與情況如何?Twitter是有記錄的早期使用者和在生產環境中使用執行Graal的公司,其他還有已經使用的場景嗎?您與非Oracle開發人員一起工作的經驗是什麼?Graal未來的開發模式會是如何的?它是否會使用和OpenJDK類似的模型?

\\
\

Wuerthinger:OpenJDK的任務和GraalVM的完全不同。

\\

OpenJDK對於開發者來說水很深,因為它總是建立一個新的語言特性或者新的庫。開發者不得不跟隨OpenJDK改變而修改程式碼,而這些改動的目的是讓社群對其價值達成共識。OpenJDK社群非常龐大,有許多不同的觀點,他們的流程主要用於幫助社群達成共識。

\\

GraalVM的目的是讓已經存在的程式碼和庫能夠更高效、在更多平臺的執行,同時擁有更多的互操作性,並且不修改語言語義(對大部分語言來說)。對於開發者介面的唯一主要部分是互操作API,它能夠允許在其他執行時環境中呼叫外部語言函式,我們儘可能保持對外介面的穩定。

\\

GraalVM支援語言的社群都有自己的發展規劃。

\\

和OpenJDK一樣,GraalVM有許多來自廠商的巨大貢獻,其中Red Hat、Intel和AMD貢獻最大。Red Hat在不久前在我們沒有多大的投入之下為GraalVM構建了一個ARM後端,這對於我們來說非常有用。你可以已經注意到Oracle最近投資了ARM,因此我們會更加關注該生態系統。

\\

這些廠商認為GraalVM將獲得足夠的認可以確保投資回報,他們的興趣主要不是自身使用。正如你指出的,Twitter也對GraalVM作出了貢獻,因為他們正在使用。其他還有一些主要的科技廠商在使用GraalVM但是沒有像Twitter那樣公佈出來,另外Oracle內部也有使用者。

\
\\

InfoQ:Oracle通常很少談論未來路線圖。您能否告訴我們在未來18個月內GraalVM的發展軌跡可能會帶給我們什麼?

\\
\

Wuerthinger:好吧,GraalVM團隊屬於Oracle實驗室,因此我們會有相反的問題,就是我們有許多公開研究性的專案,它們或多或少會超出我們在學術會議論上發表論文的範圍。Oracle實驗室有一批研究生合作者,希望通過使用GraalVM嘗試新的創意。

\\

我們有一個學生正在考慮將GraalVM連結到Chromium中,這樣我們可以在瀏覽器中使用任何語言,而不僅僅是JavaScript。但是我認為很明顯這不可能稱為Oracle的一個產品而釋出。你可以查閱GraalVM相關學術論文來了解這些瘋狂的想法。我們已經完成了對其他一些語言社群的調查,但是否支援得根據社群的興趣。

\\

關於路線圖我能夠告訴你的是,我們正在致力於支援更多的平臺。初始釋出的版本只能執行在Linux/X86和Mac/X86平臺上,以降低“釋出壓力”。我們正在積極致力於Windows平臺和ARM平臺的支援(和Red Hat一起)。對於目前被標記為“實驗性”的語言來說,例如R、Ruby和Python,還有許多穩定性和完善性的工作要做。

\\

就整合而言,我們將通過多種方式將GraalVM更深入的整合到MySQL和Oracle RDBMS中,這些會在未來18個月中看見。但是18個月後GraalVM會是什麼樣子,這非常依賴整個社群的反饋和貢獻。

\
\\

檢視英文原文:Oracle Releases GraalVM 1.0, a Polyglot Virtual Machine and Platform

\\

感謝冬雨對本文的審校。

\\

給InfoQ中文站投稿或者參與內容翻譯工作,請郵件至editors@cn.infoq.com。也歡迎大家通過新浪微博(@InfoQ@丁曉昀),微信(微訊號:InfoQChina)關注我們。

相關文章