1. 程式人生 > >Java-JVM-分類

Java-JVM-分類

Java-JVM-分類

轉載宣告:

本文系轉載自以下文章:

轉載僅為方便學習檢視,一切權利屬於原作者,本人只是做了整理和排版,如果帶來不便請聯絡我刪除。

摘要

Wikipedia那個Comparison of Java virtual machines頁面給JVM實現分得還挺細。利益相關:Azul System的員工,參與Zing VM的研發;之前在Oracle參與HotSpot VM的研發。

要說主流JVM是什麼,首先得區分清楚場景。光談部署量的話,搞不好現在部署量最多的JVM是Dalvik / ART…雖然Google會告訴大家Dalvik和ART不是“JVM”,但大家都知道骨子裡它就是不折不扣的JVM,毫無疑問。它們的設計處處有標註對JVM規範的參考,以保證語義符合JVM規範的要求;那個基於暫存器的位元組碼設計只是一種實現優化而已。

0x01 J2SE與JVM

Java EE是以Java SE為基礎的。所以並沒有“JVM for Java EE”這麼一說,只有“JVM for Java SE”,可以用於Java SE與Java EE。

在這個類別下,主流選擇有:(按流行程度遞減)

  • HotSpot VM
  • J9 VM
  • Zing VM

0x02 HotSpot VM

2.1 流行度

HotSpot VM是絕對的主流。大家用它的時候很可能就沒想過還有別的選擇,或者是為了遷就依賴了Oracle/Sun JDK某些具體實現的爛程式碼而選擇用HotSpot VM省點心。

Oracle / Sun JDK、OpenJDK的各種變種(例如IcedTea、Zulu),用的都是相同核心的HotSpot VM。

從Java SE 7開始,HotSpot VM就是Java規範的“參考實現”(RI,Reference Implementation)。也就是說,把HotSpot稱為做“標準JVM”完全不為過。可參考:
Java Platform, Standard Edition 7 Reference Implementations
Java Platform, Standard Edition 8 Reference Implementations

當大家說起“Java效能如何如何”、“Java有多少種GC”、“JVM如何調優”云云,經常預設說的就是特指HotSpot VM。可見其“主流性”。(其實這不是件好事;具體到JVM實現才可以討論的問題還是應該指明討論是基於哪個實現)

2.2 簡介

JDK8的HotSpot VM已經是以前的HotSpot VMJRockit VM的合併版,也就是傳說中的HotRockit,只是產品里名字還是叫HotSpot VM。

  • HotSpot最初並非Sun公司開發的,而是由一家名為“LongviewTechnologies”的小公司設計的,甚至這款虛擬機器一開始也不是為Java語言開發的,Sun公司注意到了這款虛擬機器在JIT編譯技術(Just In Time,即時編譯技術)上有許多優秀的理念,在1997年收購了這家公司,獲得了HotSpot VM。
    HotSpot VM的最大特點,正如其名,就是熱點程式碼探測能力。具體來說HotSpot VM的熱點程式碼探測能力可以通過執行計數器找出最具有編譯價值的程式碼,然後通知JIT編譯器以方法為單位進行編譯。如果一個方法被頻繁呼叫,或方法中有效迴圈次數很多,將會分別觸發標準編譯和OSR(棧上替換)編譯動作。通過編譯器與直譯器恰當地協同工作,可以在最優化的程式響應時間與最佳執行效能中取得平衡,而且無須等待原生代碼輸出才能執行程式,即時編譯的時間壓力也相對減小,這樣有助於引入更多的程式碼優化技術,輸出質量更高的原生代碼。
  • JRockit VM曾經號稱“世界上速度最快的Java虛擬機器”(廣告詞,貌似J9 VM也這樣說過),它是BEA公司在2002年從Appeal Virtual Machines公司收購的虛擬機器。BEA公司將其發展為一款專門為伺服器硬體和伺服器端應用場景高度優化的虛擬機器,由於專注於伺服器端應用,它可以不太關注程式啟動速度,因此JRockit內部不包含解析器實現,全部程式碼都靠即時編譯器編譯後執行。除此之外,JRockit的垃圾收集器和MissionControl服務套件等部分的實現,在眾多Java虛擬機器中也一直處於領先水平

這個合併並不是簡單地把JRockit的部分程式碼插進HotSpot裡,而是把前者一些有價值的功能在後者裡重新實現一遍。如移除PermGenJava Flight Recorderjcmd等都屬於合併專案的一部分。

不過要留意的是,這裡我說的HotSpot VM特指正常配置版,而不包括Zero / Shark版。Wikipedia那個頁面上把後者稱為Zero Port。用這個版本的人應該相當少,很多時候它的release版都build不成功…

0x03 J9 VM

J9 VM是IBM開發的一個高度模組化的JVM。

3.1 簡介

在許多平臺上,IBM J9 VM都只能跟IBM產品一起使用。這不是技術限制,而是許可證限制。例如說在Windows上IBM JDK不是免費公開的,而是要跟IBM其它產品一起捆綁釋出的;使用IBM Rational、IBM WebSphere的話都有機會用到J9 VM(也可以自己選擇配置使用別的Java SE JVM)。

根據許可證,這種捆綁在產品裡的J9 VM不應該用於執行別的Java程式…大家有沒有自己“偷偷的”拿來跑別的程式IBM也沒力氣管(咳咳而在一些IBM的硬體平臺上,很少客戶是隻買硬體不買配套軟體的,IBM給一整套解決方案,裡面可能就包括了IBM JDK。這樣自然而然就用上了J9 VM。

所以J9 VM得算在主流裡,雖然很少是大家主動選擇的首選。

3.2 效能

J9 VM的效能水平大致跟HotSpot VM是一個檔次的。有時HotSpot快些,有時J9快些。不過J9 VM有一些HotSpot VM在JDK8還不支援的功能,最顯著的一個就是J9支援AOT編譯和更強大的class data sharing

0x04 Zing VM

4.1 簡介

Zing VM是一個由Azul Systems公司從Sun HoSpot VM fork出來的一個高效能JVM,可以執行在Linux/x86-64平臺上。

Azul 公司為它重新寫了一套GC,也修改了VM內的許多實現細節,所以從我們自己的角度看,與其說它是HotSpot VM的一個變種,還不如把它看作“一個全新的JVM、只是湊巧與HotSpot VM很像”更合適。

4.2 效能

在要求低延遲、快速預熱等的場景裡,Zing VM都會比HotSpot VM表現更好

  • 支援記憶體大,GC STW時間短
    Zing的C4 GC目前可以支援1TB的-Xmx,而且GC暫停時間仍然可以維持在< 10ms的範圍裡。實際上Zing現在能支援接近2TB的-Xmx,但我們還沒能用來測試2TB場景的機器…據說再過一段時間這個測試伺服器就要到貨了。
  • 快速預熱
    Zing的ReadyNow!功能可以利用之前收集到的profile資料,引導JVM在啟動後快速達到穩定的高效能水平,減少啟動後從解釋執行到JIT編譯的等待時間。
  • 更全面的JVM監控
    -Zing自帶的ZVision / ZVRobot功能可以方便使用者監控JVM的執行狀態,從找出程式碼熱點到物件分配監控、鎖競爭監控等都可以做到。
  • 效能更優
    最關鍵的是,Zing能讓普通沒有為GC之類的底層方向調優的Java應用享有低延遲、快速預熱、易於監控的功能,為使用者節省苦苦調優的精力和時間。這是Zing的主要價值——很多Java應用都可以通過長期努力在應用/框架層面優化來提升效能,但使用Zing的話就可以更多把精力集中在業務方面。

0x05 Java SE Embedded(嵌入式定製版)

這是Oracle造出來的比較新的概念。硬體發展得很快,現在很多所謂“嵌入式”場景用的機器其實跟普通桌上型電腦的配置沒差多少,完全足以執行Java SE,侵蝕了以前高階Java ME(例如Java ME CDC Profile)的地盤。

Oracle Java SE Embedded裡帶的JVM自然還是HotSpot VM,不過是Java SE Embedded定製版:簡化了JVM內的某些部件,儘可能在支援完整的Java SE功能的前提下向著減少記憶體消耗的方向優化;只留下了Client Compiler(C1)而去掉了Server Compiler(C2);GC以前好像是隻留下了Serial GC但後來有沒有支援更多GC種類我不太清楚。

IBM在這個領域照樣可以用J9 VM應對。其它還算主流Java SE Embedded JVM的話,可能JamVM可以算進來吧。它是一個小巧的、能支援完全OpenJDK類庫和Java SE規範的JVM。

0x06 Java ME

主流有倆:

  • CLDC-HI
  • J9 VM

6.1 CLDC-HI

CLDC-HIOracle/Sun系的話,現在主流的Java ME JVM只有CLDC HotSpot Implementation(CLDC-HI,或者叫Monty VM)了。很明顯這是用於支撐Java ME CLDC Profile的JVM。

以前還有CDC HotSpot Implementation(CDC-HI,或者叫CVM),但Oracle調整了Java ME戰略之後這個VM也炮灰了。目前可能只有在Oracle ADF Mobile在iOS上的版本里還活著吧。(沒錯,iOS上可以跑Java程式的!)

戰略調整後的Java ME CLDC都快能趕上以前的Java ME CDC了。夾在Java ME CLDC與Java SE Embedded之間的Java ME CDC自然得炮灰。Sun以前在Java ME CLDC還有一個KVM,本來應該早就被CLDC-HI替代,但現在可能還有些小廠商在基於KVM定製自己的Java ME方案,畢竟更加簡單而且資源消耗更少。

6.2 J9 VM

IBM在Java ME領域對應的仍然是J9 VM。高度模組化不是吹的。

0x07 Android / Android相容系統

如同開頭說的,Android上的Dalvik / ART雖然名字不叫JVM,但骨子裡就是不折不扣的JVM。這倆VM都能支援幾乎完整的Java SE功能。跟一般Java SE相比,可能也就ClassLoader、動態生成位元組碼之類的方案比較坑爹。

Dalvik VM自身也有不少變種就是了。例如說Intel版的Dalvik x86版重寫了許多元件,JIT效能比原版Dalvik VM好。

此外,阿里雲OS的LemurVM是一個可以相容Android的Java應用的JVM。

0x08 JavaCard

Oracle/Sun有JCVM。其它支援JavaCard的JVM我還真沒怎麼留意。會用到這種解決方案的都是政府或者企業使用者吧…不是我能接觸到的領域。

0x09 Sun SPOT

Sun SPOT上有個Squawk VM,是一個非常小巧、專門為小型嵌入式環境設計的JVM。

0x10 研究性質的JVM

去找比較新的、跟JVM相關的學術界的研究論文,基本上就下面幾個JVM可選:

  • Jikes RVM
  • Maxine VM
  • Graal VM

這仨就算是現在的主流研究性JVM吧。

10.1 Jikes RVM

Jikes RVM是IBM開發的專門用來研究JVM實現技術的專案。曾用名Jalapeño。它是一個元迴圈虛擬機器(metacircular VM),整個JVM都是用Java實現的

最有趣的地方是它有一個名為MMTk的框架:Jikes RVM - MMTk,可以很方便的編寫新的GC演算法插入到Jikes RVM裡去,而且已有的實現的選擇也很豐富。所以很多研究GC演算法的論文會選擇基於Jikes RVM/MMTk來做初步實現,不但做起來容易,還可以很方便的與別的演算法對比。

10.2 Maxine VM

Maxine VM是Oracle/Sun Labs開發的研究專案。跟Jikes RVM一樣是元迴圈虛擬機器。

Maxine VM自從有了C1X/T1X編譯器之後,效能似乎就超過了Jikes RVM;有了Graal編譯器之後更加壓倒Jikes RVM。做JIT編譯器研究的話我會選擇用Maxine VM。

10.3 Graal VM

Graal VM就是Maxine VM的Graal編譯器插在HotSpot VM上。現在Oracle Labs和一些大學做JIT編譯器研究都是基於Graal VM來做的,效果出奇的好,效能基本跟HotSpot Server Compiler(C2)持平甚至有所超越。勢頭正猛。

以前百家爭鳴的時候,研究性JVM或配套的JIT編譯器那也是多得要命。ORP、OpenJIT、Moxie、Joeq、CACAO、SableVM、VMKit、Sun ExactVM / ResearchVM…隨便列幾個。

更多文章

這裡不是轉載的。

Java虛擬機器進階之一:Java VM前世今生