1. 各種虛擬機的發展歷史


Sun Classic VM :


以今天的視角來看,Sun Classic VM的技術可能很原始,這款虛擬機的使命也早已終結。但僅憑它“世界上第一款商用Java虛擬機”的頭銜,就足夠有讓歷史記住它的理由。 1996年1月23日,Sun公司發布JDK 1.0,Java語言首次擁有了商用的正式運行環境,這個JDK中所帶的虛擬機就是Classic VM。這款虛擬機只能使用純解釋器方式來執行Java代碼,如果要使用JIT編譯器,就必須進行外掛。但是假如外掛了JIT編譯器,JIT編譯器就完全接管了虛擬機的執行系統,解釋器便不再工作了。用戶在這款虛擬機上執行java -version命令,將會看到類似下面這行輸出:其中的“sunwjit”就是Sun提供的外掛編譯器,其他類似的外掛編譯器還有Symantec JIT和shuJIT等。由於解釋器和編譯器不能配合工作,這就意味着如果要使用編譯器執行,編譯器就不得不對每一個方法、每一行代碼都進行編譯,而無論它們執行的頻率是否具有編譯的價值。基於程序響應時間的壓力,這些編譯器根本不敢應用編譯耗時稍高的優化技術,因此這個階段的虛擬機即使用了JIT編譯器輸出本地代碼,執行效率也和傳統的C/C++程序有很大差距,“Java語言很慢”的形象就是在這時候開始在用戶心中樹立起來的。 Sun的虛擬機團隊努力去解決Classic VM所面臨的各種問題,提升運行效率。在JDK 1.2時,曾在Solaris平台上發布過一款名為Exact VM的虛擬機,它的執行系統已經具備現代高性能虛擬機的雛形:如兩級即時編譯器、編譯器與解釋器混合工作模式等。Exact VM因它使用准確式內存管理(Exact Memory Management,也可以叫Non-Conservative/Accurate Memory Management)而得名,即虛擬機可以知道內存中某個位置的數據具體是什么類型。譬如內存中有一個32位的整數123456,它到底是一個reference類型指向123456的內存地址還是一個數值為123456的整數,虛擬機將有能力分辨出來,這樣才能在GC(垃圾收集)的時候准確判斷堆上的數據是否還可能被使用。由於使用了准確式內存管理,Exact VM可以拋棄以前Classic VM基於handler的對象查找方式(原因是進行GC后對象將可能會被移動位置,如果將地址為123456的對象移動到654321,在沒有明確信息表明內存中哪些數據是reference的前提下,虛擬機是不敢把內存中所有為123456的值改成654321的,所以要使用句柄來保持reference值的穩定),這樣每次定位對象都少了一次間接查找的開銷,提升執行性能。 雖然Exact VM的技術相對Classic VM來說先進了許多,但是在商業應用上只存在了很短暫的時間就被更為優秀的HotSpot VM所取代,甚至還沒有來得及發布Windows和Linux平台下的商用版本。而Classic VM的生命周期則相對長了許多,它在JDK 1.2之前是Sun JDK中唯一的虛擬機,在JDK 1.2時,它與HotSpot VM並存,但默認使用的是Classic VM(用戶可用java-hotspot參數切換至HotSpot VM),而在JDK 1.3時,HotSpot VM成為默認虛擬機,但Classic VM仍作為虛擬機的“備用選擇”發布(使用java-classic參數切換),直到JDK 1.4的時候,Classic VM才完全退出商用虛擬機的歷史舞台,與Exact VM一起進入了Sun Labs Research VM之中。


 

Sun HotSpot VM:


提起HotSpot VM,相信所有Java程序員都知道,它是Sun JDK和OpenJDK中所帶的虛擬機,也是目前使用范圍最廣的Java虛擬機。但不一定所有人都知道的是,這個目前看起來“血統純正”的虛擬機在最初並非由Sun公司開發,而是由一家名為“Longview Technologies”的小公司設計的;甚至這個虛擬機最初並非是為Java語言而開發的,它來源於Strongtalk VM,而這款虛擬機中相當多的技術又是來源於一款支持Self語言實現“達到C語言50%以上的執行效率”的目標而設計的虛擬機,Sun公司注意到了這款虛擬機在JIT編譯上有許多優秀的理念和實際效果,在1997年收購了Longview Technologies公司,從而獲得了HotSpot VM。HotSpot VM既繼承了Sun之前兩款商用虛擬機的優點(如前面提到的准確式內存管理),也有許多自己新的技術優勢,如它名稱中的HotSpot指的就是它的熱點代碼探測技術(其實兩個VM基本上是同時期的獨立產品,HotSpot還稍早一些,HotSpot一開始就是准確式GC,而Exact VM之中也有與HotSpot幾乎一樣的熱點探測。為了Exact VM和HotSpot VM哪個成為Sun主要支持的VM產品,在Sun公司內部還有過爭論,HotSpot打敗Exact並不能算技術上的勝利),HotSpot VM的熱點代碼探測能力可以通過執行計數器找出最具有編譯價值的代碼,然后通知JIT編譯器以方法為單位進行編譯。如果一個方法被頻繁調用,或方法中有效循環次數很多,將會分別觸發標准編譯和OSR(棧上替換)編譯動作。通過編譯器與解釋器恰當地協同工作,可以在最優化的程序響應時間與最佳執行性能中取得平衡,而且無須等待本地代碼輸出才能執行程序,即時編譯的時間壓力也相對減小,這樣有助於引入更多的代碼優化技術,輸出質量更高的本地代碼。在2006年的JavaOne大會上,Sun公司宣布最終會把Java開源,並在隨后的一年,陸續將JDK的各個部分(其中當然也包括了HotSpot VM)在GPL協議下公開了源碼,並在此基礎上建立了OpenJDK。這樣,HotSpot VM便成為了Sun JDK和OpenJDK兩個實現極度接近的JDK項目的共同虛擬機。在2008年和2009年,Oracle公司分別收購了BEA公司和Sun公司,這樣Oracle就同時擁有了兩款優秀的Java虛擬機:JRockit VM和HotSpot VM。Oracle公司宣布在不久的將來(大約應在發布JDK 8的時候)會完成這兩款虛擬機的整合工作,使之優勢互補。整合的方式大致上是在HotSpot的基礎上,移植JRockit的優秀特性,譬如使用JRockit的垃圾回收器與MissionControl服務,使用HotSpot的JIT編譯器與混合的運行時系統。


 

Sun Mobile-Embedded VM / Meta-Circular VM:


Sun公司所研發的虛擬機可不僅有前面介紹的服務器、桌面領域的商用虛擬機,除此之外,Sun公司面對移動和嵌入式市場,也發布過虛擬機產品,另外還有一類虛擬機,在設計之初就沒抱有商用的目的,僅僅是用於研究、驗證某種技術和觀點,又或者是作為一些規范的標准實現。這些虛擬機對於大部分不從事相關領域開發的Java程序員來說可能比較陌生。Sun公司發布的其他Java虛擬機有: (1)KVMKVM中的K是“Kilobyte”的意思,它強調簡單、輕量、高度可移植,但是運行速度比較慢。在Android、iOS等智能手機操作系統出現前曾經在手機平台上得到非常廣泛的應用。 (2)CDC/CLDC HotSpot Implementation>CDC/CLDC全稱是Connected(Limited)Device Configuration,在JSR-139/JSR-218規范中進行定義,它希望在手機、電子書、PDA等設備上建立統一的Java編程接口,而CDC-HI VM和CLDC-HI VM則是它們的一組參考實現。CDC/CLDC是整個Java ME的重要支柱,但從目前Android和iOS二分天下的移動數字設備市場看來,在這個領域中,Sun的虛擬機所面臨的局面遠不如服務器和桌面領域樂觀。 (3)Squawk VM Squawk VM由Sun公司開發,運行於Sun SPOT(Sun Small Programmable Object Technology,一種手持的WiFi設備),也曾經運用於Java Card。這是一個Java代碼比重很高的嵌入式虛擬機實現,其中諸如類加載器、字節碼驗證器、垃圾收集器、解釋器、編譯器和線程調度都是Java語言本身完成的,僅僅靠C語言來編寫設備I/O和必要的本地代碼。 (4)JavaInJava JavaInJava是Sun公司於1997年~1998年間研發的一個實驗室性質的虛擬機,從名字就可以看出,它試圖以Java語言來實現Java語言本身的運行環境,既所謂的“元循環”(Meta-Circular,是指使用語言自身來實現其運行環境)。它必須運行在另外一個宿主虛擬機之上,內部沒有JIT編譯器,代碼只能以解釋模式執行。在20世紀末主流Java虛擬機都未能很好解決性能問題的時代,開發這種項目,其執行速度可想而知。 (5)Maxine VMMaxine VM 和上面的JavaInJava非常相似,它也是一個幾乎全部以Java代碼實現(只有用於啟動JVM的加載器使用C語言編寫)的元循環Java虛擬機。這個項目於2005年開始,到現在仍然在發展之中,比起JavaInJava,Maxine VM就顯得“靠譜”很多,它有先進的JIT編譯器和垃圾收集器(但沒有解釋器),可在宿主模式或獨立模式下執行,其執行效率已經接近了HotSpot Client VM的水平。


 

BEA JRockit / IBM J9 VM:


前面介紹了Sun公司的各種虛擬機,除了Sun公司以外,其他組織、公司也研發過不少虛擬機實現,其中規模最大、最著名的就是BEA和IBM公司了。JRockit VM曾經號稱“世界上速度最快的Java虛擬機”(廣告詞,貌似J9 VM也這樣說過),它是BEA公司在2002年從Appeal Virtual Machines公司收購的虛擬機。BEA公司將其發展為一款專門為服務器硬件和服務器端應用場景高度優化的虛擬機,由於專注於服務器端應用,它可以不太關注程序啟動速度,因此JRockit內部不包含解析器實現,全部代碼都靠即時編譯器編譯后執行。除此之外,JRockit的垃圾收集器和MissionControl服務套件等部分的實現,在眾多Java虛擬機中也一直處於領先水平。 IBM J9 VM並不是IBM公司唯一的Java虛擬機,不過是目前其主力發展的Java虛擬機。IBM J9 VM原本是內部開發代號,正式名稱是“IBM Technology for Java Virtual Machine”,簡稱IT4J,只是這個名字太拗口了一點,普及程度不如J9。J9 VM最初是由IBM Ottawa實驗室一個名為SmallTalk的虛擬機擴展而來的,當時這個虛擬機有一個bug是由8k值定義錯誤引起的,工程師花了很長時間終於發現並解決了這個錯誤,此后這個版本的虛擬機就稱為K8了,后來擴展出支持Java的虛擬機就被稱為J9了。與BEA JRockit專注於服務器端應用不同,IBM J9的市場定位與Sun HotSpot比較接近,它是一款設計上從服務器端到桌面應用再到嵌入式都全面考慮的多用途虛擬機,J9的開發目的是作為IBM公司各種Java產品的執行平台,它的主要市場是和IBM產品(如IBM WebSphere等)搭配以及在IBM AIX和z/OS這些平台上部署Java應用。


 

 Azul VM / BEA Liquid VM:


我們平時所提及的“高性能Java虛擬機”一般是指HotSpot、JRockit、J9這類在通用平台上運行的商用虛擬機,但其實Azul VM和BEA Liquid VM這類特定硬件平台專有的虛擬機才是“高性能”的武器。Azul VM是Azul Systems 公司在HotSpot基礎上進行大量改進,運行於Azul Systems公司的專有硬件Vega系統上的Java虛擬機,每個Azul VM實例都可以管理至少數十個CPU和數百GB內存的硬件資源,並提供在巨大內存范圍內實現可控的GC時間的垃圾收集器、為專有硬件優化的線程調度等優秀特性。在2010年,Azul Systems公司開始從硬件轉向軟件,發布了自己的Zing JVM,可以在通用x86平台上提供接近於Vega系統的特性。Liquid VM即是現在的JRockit VE(Virtual Edition),它是BEA公司開發的,可以直接運行在自家Hypervisor系統上的JRockit VM的虛擬化版本,Liquid VM不需要操作系統的支持,或者說它自己本身實現了一個專用操作系統的必要功能,如文件系統、網絡支持等。由虛擬機越過通用操作系統直接控制硬件可以獲得很多好處,如在線程調度時,不需要再進行內核態/用戶態的切換等,這樣可以最大限度地發揮硬件的能力,提升Java程序的執行性能。


 

 Apache Harmony / Google Android Dalvik VM:


這節介紹的Harmony VM和Dalvik VM只能稱做“虛擬機”,而不能稱做“Java虛擬機”,但是這兩款虛擬機(以及所代表的技術體系)對最近幾年的Java世界產生了非常大的影響和挑戰,甚至有些悲觀的評論家認為成熟的Java生態系統有崩潰的可能。Apache Harmony是一個Apache軟件基金會旗下以Apache License協議開源的實際兼容於JDK 1.5和JDK 1.6的Java程序運行平台,這個介紹相當拗口。它包含自己的虛擬機和Java庫,用戶可以在上面運行Eclipse、Tomcat、Maven等常見的Java程序,但是它沒有通過TCK認證,所以我們不得不用那么一長串拗口的語言來介紹它,而不能用一句“Apache的JDK”來說明。如果一個公司要宣布自己的運行平台“兼容於Java語言”,那就必須要通過TCK(Technology Compatibility Kit)的兼容性測試。Apache基金會曾要求Sun公司提供TCK的使用授權,但是一直遭到拒絕,直到Oracle公司收購了Sun公司之后,雙方關系越鬧越僵,最終導致Apache憤然退出JCP(Java Community Process)組織,這是目前為止Java社區最嚴重的一次“分裂”。在Sun將JDK開源形成OpenJDK之后,Apache Harmony開源的優勢被極大地削弱,甚至連Harmony項目的最大參與者IBM公司也宣布辭去Harmony項目管理主*的職位,並參與OpenJDK項目的開發。雖然Harmony沒有經過真正大規模的商業運用,但是它的許多代碼(基本上是Java庫部分的代碼)被吸納進IBM的JDK 7實現及Google Android SDK之中,尤其是對Android的發展起到了很大的推動作用。說到Android,這個時下最熱門的移動數碼設備平台在最近幾年間的發展過程中所取得的成果已經遠遠超越了Java ME在過去十多年所獲得的成果,Android讓Java語言真正走進了移動數碼設備領域,只是走的並非Sun公司原本想象的那一條路。Dalvik VM是Android平台的核心組成部分之一,它的名字來源於冰島一個名為Dalvik的小漁村。Dalvik VM並不是一個Java虛擬機,它沒有遵循Java虛擬機規范,不能直接執行Java的Class文件,使用的是寄存器架構而不是JVM中常見的棧架構。但是它與Java又有着千絲萬縷的聯系,它執行的dex(Dalvik Executable)文件可以通過Class文件轉化而來,使用Java語法編寫應用程序,可以直接使用大部分的Java API等。目前Dalvik VM隨着Android一起處於迅猛發展階段,在Android 2.2中已提供即時編譯器實現,在執行性能上有了很大的提高。


 

 Microsoft JVM:


及其他在十幾年的Java虛擬機發展過程中,除去上面介紹的那些被大規模商業應用過的Java虛擬機外,還有許多虛擬機是不為人知的或者曾經“絢麗”過但最終湮滅的。我們以其中微軟公司的JVM為例來介紹一下。也許Java程序員聽起來可能會覺得驚訝,微軟公司曾經是Java技術的鐵桿支持者(也必須承認,與Sun公司爭奪Java的控制權,令Java從跨平台技術變為綁定在Windows上的技術是微軟公司的主要目的)。在Java語言誕生的初期(1996年~1998年,以JDK 1.2發布為分界),它的主要應用之一是在瀏覽器中運行Java Applets程序,微軟公司為了在IE3中支持Java Applets應用而開發了自己的Java虛擬機,雖然這款虛擬機只有Windows平台的版本,卻是當時Windows下性能最好的Java虛擬機,它在1997年和1998年連續兩年獲得了《PC Magazine》雜志的“編輯選擇獎”。但好景不長,在1997年10月,Sun公司正式以侵犯商標、不正當競爭等罪名控告微軟公司,在隨后對微軟公司的壟斷調查之中,這款虛擬機也曾作為證據之一被呈送法庭。這場官司的結果是微軟公司賠償2000萬美金給Sun公司(最終微軟公司因壟斷賠償給Sun公司的總金額高達10億美元),承諾終止其Java虛擬機的發展,並逐步在產品中移除Java虛擬機相關功能。具有諷刺意味的是,到最后在Windows XP SP3中Java虛擬機被完全抹去的時候,Sun公司卻又到處登報希望微軟公司不要這樣做。Windows XP高級產品經理Jim Cullinan稱:“我們花費了3年的時間和Sun打官司,當時他們試圖阻止我們在Windows中支持Java,現在我們這樣做了,可他們又在抱怨,這太具有諷刺意味了。

 下一篇Java內存區域介紹

部分內容轉載至:http://201610042321.iteye.com/blog/2337901

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM