Java虚拟机家族考
http://www.infoq.com/cn/articles/jvm-family
說起Java虛擬機,許多Java程序員都會潛意識地把它與Sun[1] HotSpot虛擬機等同看待,也許還有一些程序員會注意到BEA JRockit和IBM J9,但大多數(shù)人對JVM的認識都僅限于此了。
相關(guān)廠商內(nèi)容
支付寶與烏云分享架構(gòu)安全設(shè)計指南
西門子如何系統(tǒng)培養(yǎng)架構(gòu)師以及內(nèi)部系統(tǒng)架構(gòu)解密
相關(guān)贊助商
ArchSummit全球架構(gòu)師峰會報名啟動!8折優(yōu)惠,6月30日截止!
從1996年初Sun發(fā)布的JDK 1.0中所包含的Sun Classic VM算起,Java虛擬機已經(jīng)發(fā)展了15個年頭,滄海桑田一瞬間,15年轉(zhuǎn)眼而過,這期間曾經(jīng)涌現(xiàn)、湮滅過許多或經(jīng)典或優(yōu)秀或有特色的虛擬機實現(xiàn),在《Java虛擬機專欄》的第1篇中,我們先暫且把代碼與技術(shù)放下,一起來回顧一下Java虛擬機家族的發(fā)展軌跡和歷史變遷。
虛擬機始祖:Sun Classic / Exact VM
以今天的視角來看,Sun Classic VM的技術(shù)可能很原始,這款虛擬機的使命也早已終結(jié)。但僅憑它 “世界上第一款商用Java虛擬機”的頭銜,就足夠有令歷史有記住它的理由。
1996年1月23日,Sun發(fā)布JDK 1.0,Java語言首次擁有了商用的正式運行環(huán)境,這個JDK中所帶的虛擬機就是Classic VM。這款虛擬機只能使用純解釋器方式來執(zhí)行Java代碼,如果要使用JIT編譯器那就必須進行外掛,但是假如外掛了JIT編譯器,JIT編譯器就完全接管了虛擬機的執(zhí)行系統(tǒng),解釋器便不再工作了。用戶在這款虛擬機上執(zhí)行java –version命令,將會看到類似下面這行的輸出:
java version "1.2.2" Classic VM (build JDK-1.2.2-001, green threads, sunwjit)其中的“sunwjit”就是Sun提供的外掛編譯器,其他類似的外掛編譯器還有Symantec JIT和shuJIT等。由于解釋器和編譯器不能配合工作,這就意味著如果要使用編譯器執(zhí)行,編譯器就不得不為對每一個方法,每一行代碼都進行編譯,而無論它們執(zhí)行的頻率是否具有編譯的價值。基于程序響應(yīng)時間的壓力,這些編譯器根本不敢應(yīng)用編譯耗時稍高的優(yōu)化技術(shù),因此這個階段的虛擬機即使用了JIT編譯器輸出本地代碼,執(zhí)行效率也和傳統(tǒng)的C/C++程序有很大差距,“Java語言很慢”的形象就是在這時候開始在用戶心中樹立起來的。
Sun的虛擬機團隊努力去解決Classic VM所面臨的各種問題,提升運行效率,在JDK 1.2時,曾在Solaris平臺上發(fā)布過一款名為Exact VM的虛擬機,它的執(zhí)行系統(tǒng)已經(jīng)具備現(xiàn)代高性能虛擬機雛形:如兩級即時編譯器、編譯器與解釋器混合工作模式等。Exact VM因它使用準確式內(nèi)存管理(Exact Memory Management,也可以叫Non-Conservative/Accurate Memory Management)而得名,即虛擬機可以知道內(nèi)存中某個位置的數(shù)據(jù)具體是什么類型。譬如內(nèi)存中有一個32bit的整數(shù)123456,它到底是一個reference類型指向123456的內(nèi)存地址還是一個數(shù)值為123456的整數(shù),虛擬機將有能力分辨出來,這樣才能在GC的時候準確判斷堆上的數(shù)據(jù)是否還可能被使用。由于使用了準確式內(nèi)存管理,Exact VM可以拋棄掉以前Classic VM基于handler的對象查找方式(原因是GC后對象將可能會被移動位置,如果地址為123456的對象移動到654321,在沒有明確信息表明內(nèi)存中哪些數(shù)據(jù)是reference的前提下,那虛擬機是不敢把內(nèi)存中所有為123456的值改成654321的,所以要使用句柄來保持reference值的穩(wěn)定),這樣每次定位對象都少了一次間接查找的開銷,提升執(zhí)行性能。
雖然Exact VM的技術(shù)相對Classic VM來說先進了許多,但是它命運顯得十分英雄氣短,在商業(yè)應(yīng)用上只存在了很短暫的時間就被更為優(yōu)秀的HotSpot VM所取代,甚至還沒有來得及發(fā)布Windows和Linux平臺下的商用版本。而Classic VM的生命周期則相對長了許多,它在JDK 1.2之前是Sun JDK中唯一的虛擬機,在JDK 1.2時,它與HotSpot VM并存,但默認是使用Classic VM(用戶可用java –hotspot參數(shù)切換至HotSpot VM),而在JDK 1.3時,HotSpot VM成為默認虛擬機,它仍作為虛擬機的“備用選擇”發(fā)布(使用java –classic參數(shù)切換),直到JDK 1.4的時候,Classic VM才正式退出商用虛擬機的歷史舞臺,與Exact VM一起進入了Sun Labs Research VM之中。
武林盟主:Sun HotSpot VM
HotSpot VM相信所有Java程序員都知道,它是Sun JDK和OpenJDK中所帶的虛擬機,也是目前使用范圍最廣的Java虛擬機。但不一定所有人都知道的是,這個目前看起來“血統(tǒng)純正”的虛擬機在最初并非由Sun公司開發(fā),而是由一家名為“Longview Technologies”的小公司設(shè)計的;甚至這個虛擬機最初并非是為Java語言而開發(fā)的,它來源于Strongtalk語言,而虛擬機中相當多的技術(shù)又是來源于一款支持Self語言實現(xiàn)“達到C語言50%以上的執(zhí)行效率”的目標而設(shè)計的虛擬機,Sun公司注意到了這款虛擬機在JIT編譯上有許多優(yōu)秀的理念和實際效果,在1997年收購了Longview Technologies公司,從而獲得了HotSpot VM。
HotSpot VM既繼承了Sun之前兩款商用虛擬機的優(yōu)點(如前面提到的準確式內(nèi)存管理),也有許多自己新的技術(shù)優(yōu)勢,如它名稱中的HotSpot指的就是它的熱點代碼探測技術(shù)(其實Exact VM之中也有與HotSpot幾乎一樣的熱點探測,為了Exact VM和HotSpot VM哪個成為Sun主要支持的產(chǎn)品VM,在Sun公司內(nèi)部還大吵過一場,HotSpot打敗Exact并不能算技術(shù)上的勝利),HotSpot VM的熱點代碼探測能力可以通過執(zhí)行計數(shù)器找出最具優(yōu)編譯價值的代碼,然后通知JIT編譯器以方法為單位進行編譯。如果一個方法被頻繁調(diào)用,或方法中回邊(回邊是指程序向后跳轉(zhuǎn)的行為)次數(shù)很多,將會分別觸發(fā)標準編譯和OSR(棧上替換)編譯動作。通過編譯器與解釋器恰當?shù)貐f(xié)同工作,可以在最優(yōu)化的程序響應(yīng)時間與最佳執(zhí)行性能中取得平衡,而且無需等待本地代碼輸出才能執(zhí)行程序,即時編譯的時間壓力也相對減小,這樣有助于引入更多的代碼優(yōu)化技術(shù),輸出質(zhì)量更高的本地代碼。
2006年的JavaOne大會上,Sun宣布最終會把Java開源,并在隨后的一年,陸續(xù)地將JDK的各個部分(其中當然也包括了HotSpot VM)在GPL協(xié)議下公開了源碼,并在此基礎(chǔ)上建立了OpenJDK。這樣,HotSpot VM便成為了Sun JDK和OpenJDK兩個實現(xiàn)極度接近的JDK項目的共同虛擬機。
在2008年和2010年,Oracle分別收購了BEA和Sun公司,這樣Oracle就同時擁有了這個星球上最優(yōu)秀的兩款Java虛擬機:JRockit VM和HotSpot VM。Oracle宣布在不久的將來(大約應(yīng)在JDK 8的時候)會完成這兩款虛擬機的整合工作,使之優(yōu)勢互補。整合的方式大致上是在HotSpot的基礎(chǔ)上,移植JRockit的優(yōu)秀特性,譬如使用JRockit的垃圾回收器與MissionControl服務(wù),使用HotSpot的JIT編譯器與混合的運行時系統(tǒng)。當HotSpot吸收了JRockit的全部功力之后,能否一統(tǒng)虛擬機的江湖,成為真正的武林盟主,我們拭目以待。
小數(shù)派:Sun Mobile-Embedded VM / Meta-Circular VM
Sun公司所研發(fā)的虛擬機可不僅有前面介紹到的服務(wù)器、桌面領(lǐng)域的商用虛擬機,除此之外,Sun面對移動和嵌入式市場,也發(fā)布過虛擬機產(chǎn)品,另外還有一類虛擬機,在設(shè)計之初就沒有抱著商用的目的,僅僅是用于研究、驗證某種技術(shù)和觀點,又或者是作為一些規(guī)范的標準實現(xiàn)。這些虛擬機對于大部分不從事相關(guān)領(lǐng)域開發(fā)的Java程序員來說可能比較陌生,Sun公司發(fā)布的其他Java虛擬機有:
- KVM
KVM中的K是“Kilobyte”的意思,它強調(diào)簡單,輕量,高度可移植,但是運行速度比較慢。在Androd、iOS等智能手機操作系統(tǒng)出現(xiàn)前曾經(jīng)在手機平臺上得到非常廣泛應(yīng)用。
- CDC/CLDC HotSpot
CDC/CLDC全稱是Connected(Limited)Device Configuration,在JSR-139/JSR-218規(guī)范中進行定義,它希望在手機、電子書、PDA等設(shè)備上建立統(tǒng)一的Java編程接口,而CDC HotSpot VM和CLDC HotSpot VM則是它們的一組參考實現(xiàn)。CDC/CLDC是整個Java ME的重要支柱,但從目前Android和Apple iOS二分天下的移動數(shù)字設(shè)備市場看來,在這個領(lǐng)域中,Sun的虛擬機所面臨的局面遠不如服務(wù)器和桌面領(lǐng)域樂觀。
- Squawk VM
Squawk VM是由Sun開發(fā),運行于Sun SPOT(Sun Small Programmable Object Technology,一種手持的Wifi設(shè)備),也曾經(jīng)運用于Java Card。這是一個Java代碼比重很高的嵌入式虛擬機實現(xiàn),其中諸如類加載器、字節(jié)碼驗證器、垃圾收集器、解釋器、編譯器和線程調(diào)度都是Java語言本身所完成的,僅僅靠C語言來編寫設(shè)備I/O和必要的本地代碼。
- JavaInJava
JavaInJava是Sun公司1997年~1998年間所研發(fā)的一個實驗室性質(zhì)的虛擬機,從名字就可以看出,它試圖以Java語言來實現(xiàn)Java語言本身的運行環(huán)境,既所謂的“元循環(huán)”(Meta-Circular,是指使用語言自身來實現(xiàn)其運行環(huán)境)。它必須運行在另外一個宿主虛擬機之上,內(nèi)部沒有JIT編譯器,代碼只能以解釋模式執(zhí)行。在上世紀末主流Java虛擬機都未能很好解決性能問題的時代,開發(fā)這種項目,其執(zhí)行速度大家可想而知。
- Maxine VM
Maxine VM和上面的JavaInJava非常相似,它也是一個幾乎全部以Java代碼實現(xiàn)(只有用于啟動JVM的加載器使用C語言編寫)的元循環(huán)Java虛擬機。這個項目于2005年開始,到現(xiàn)在仍然在發(fā)展之中,比起JavaInJava,Maxine VM就顯得“靠譜”很多,它有先進的JIT編譯器和垃圾收集器(但沒有解釋器),可在宿主模式或獨立模式下執(zhí)行,其執(zhí)行效率已經(jīng)接近了HotSpot Client VM的水平。
百家爭鳴:BEA JRockit / IBM J9 VM
前面介紹了Sun公司的各種虛擬機,除了Sun公司以外,其他組織、公司也研發(fā)過不少虛擬機實現(xiàn),其中規(guī)模最大、最著名的就是BEA和IBM公司了。
JRockit VM曾經(jīng)號稱“世界上速度最快的Java虛擬機”(廣告詞,貌似J9 VM也這樣說過),它是BEA公司在2002年從Appeal Virtual Machines公司收購獲得的虛擬機。BEA將其發(fā)展為一款專門為服務(wù)器硬件和服務(wù)端應(yīng)用場景高度優(yōu)化的虛擬機,由于專注于服務(wù)端應(yīng)用,它可以不太關(guān)注于程序啟動速度,因此JRockit內(nèi)部不包含解析器實現(xiàn),全部代碼都靠即時編譯器編譯后執(zhí)行。除此之外,JRockit的垃圾收集器和MissionControl服務(wù)套件等部分的實現(xiàn),在眾多Java虛擬機中也一直處于領(lǐng)先水平。
IBM J9 VM并不是IBM公司唯一的Java虛擬機,不過是目前IBM主力發(fā)展的Java虛擬機,J9原本是內(nèi)部開發(fā)代號,正式名稱是“IBM Technology for Java Virtual Machine”,簡稱IT4J,只是這個名字太拗口了一點,普及程度不如J9。J9 VM最初是由IBM Ottawa實驗室一個SmallTalk的虛擬機擴展而來的,當時這個虛擬機有一個bug是因為8k值定義錯誤引起,工程師們花了很長時間終于發(fā)現(xiàn)并解決了這個錯誤,此后這個版本的虛擬機就被稱為K8了,后來擴展出支持Java的虛擬機就被稱為J9了。與BEA JRockit專注于服務(wù)端應(yīng)用不同,IBM J9的市場定位與Sun HotSpot比較接近,它是一款設(shè)計上從服務(wù)端到桌面應(yīng)用再到嵌入式都全面考慮的多用途虛擬機,J9的開發(fā)目的是作為IBM公司各種Java產(chǎn)品的執(zhí)行平臺,它的主要市場在和IBM產(chǎn)品(如IBM WebSphere等)搭配以及在IBM AIX和z/OS這些平臺上部署Java應(yīng)用。
除了BEA和IBM外,其他一些大公司如HP、SAP等也號稱有自己的專屬JDK和虛擬機,但是它們是通過從Sun購買版權(quán)的方式獲得的,并非自己獨立開發(fā)。
最終兵器:Azul VM/BEA Liquid VM
我們平時所提及的“高性能Java虛擬機”一般是指HotSpot、JRockit、J9這類在通用平臺上運行的商用虛擬機,但其實Azul VM和BEA Liquid VM這類特定硬件平臺專有的虛擬機才是“高性能”的最終兵器。
Azul VM是Azul Systems 公司在HotSpot基礎(chǔ)上進行大量改進,運行于Azul Systems 公司的專有硬件Vega系統(tǒng)上的Java虛擬機,每個Azul VM實例都可以管理至少數(shù)十個CPU和數(shù)百GB的內(nèi)存的硬件資源,并提供在巨大內(nèi)存范圍內(nèi)實現(xiàn)可控的GC時間的垃圾收集器、為專有硬件優(yōu)化的線程調(diào)度等優(yōu)秀特性。在2010年,Azul開始從硬件轉(zhuǎn)向軟件,發(fā)布了自己的Zing JVM,可以在通用x86平臺上提供接近于Vega系統(tǒng)的特性。
Liquid VM是BEA公司開發(fā)的,可以直接運行在自家Hypervisor系統(tǒng)上的JRockit VM的虛擬化版本,Liquid VM不需要操作系統(tǒng)的支持,或者說它自己本身實現(xiàn)了一個專用操作系統(tǒng)的必要功能,如文件系統(tǒng)、網(wǎng)絡(luò)支持等。由虛擬機越過通用操作系統(tǒng)直接控制硬件可以獲得很多好處,如在線程調(diào)度時,不需要再進行內(nèi)核態(tài)/用戶態(tài)的切換等,這樣可以最大限度地發(fā)揮硬件的能力,提升Java程序的執(zhí)行性能。
挑戰(zhàn)者:Apache Harmony / Google Android Dalvik VM
這節(jié)介紹的Harmony VM和Dalvik VM只能稱作“虛擬機”,而不能稱作“Java虛擬機”,但是這兩款虛擬機(以及所代表的技術(shù)體系)對最近三年的Java世界產(chǎn)生了非常大的影響和挑戰(zhàn),甚至有悲觀的評論家認為成熟的Java生態(tài)系統(tǒng)有崩潰的可能。
Apache Harmony是一個Apache軟件基金會旗下以Apache License協(xié)議開源的實際兼容于JDK 1.5和JDK 1.6的Java程序運行平臺,這個介紹相當拗口。它包含自己的虛擬機和Java庫,用戶可以在上面運行Eclipse、Tomcat、Maven等常見的Java程序,但是……它沒有通過TCK認證,所以我們不得不用那么一長串拗口的語言來介紹它,而不能用一句“Apache的JDK”來說明。如果一個公司要宣布自己的運行平臺“兼容于Java語言”,那就必須要通過TCK(Technology Compatibility Kit)的兼容性測試,Apache基金會曾要求Sun公司提供TCK的使用授權(quán),但是一直遭到拒絕,直到Oracle收購了Sun公司之后,雙方關(guān)系越鬧越僵,最終導致Apache憤然退出JCP(Java Community Process)組織,這是近代Java社區(qū)最嚴重的一次分裂。
在Sun把JDK開源形成OpenJDK之后,Apache Harmony開源的優(yōu)勢被極大地削弱,甚至連Harmony項目的最大參與者IBM公司也宣布辭去Harmony項目管理主席的職位,參與OpenJDK項目的開發(fā)。雖然Harmony沒有真正大規(guī)模商業(yè)運用過,但是它的許多代碼(基本上是Java庫部分的代碼)被吸納進IBM的JDK7實現(xiàn)以及Google Android SDK之中,尤其是對Android的發(fā)展起了很大推動作用。
說到Android,這個時下最熱門的移動數(shù)碼設(shè)備平臺在最近3年間的發(fā)展所取得的成果已經(jīng)遠遠超越了Java ME在過去十多年所獲得的成果,Android讓Java語言真正走進了移動數(shù)碼設(shè)備領(lǐng)域,只是走的并非Sun公司原本想象的那一條路。
Dalvik VM是Android平臺的核心組成部分之一,它名字來源于冰島一個名為Dalvik的小漁村。Dalvik VM并不是一個Java虛擬機,它沒有遵循Java虛擬機規(guī)范,不能直接執(zhí)行Java的class文件,使用寄存器架構(gòu)而不是JVM中常見的棧架構(gòu)。但是它與Java卻又有著千絲萬縷的聯(lián)系,它執(zhí)行dex(Dalvik Executable)文件可以通過class文件轉(zhuǎn)化而來,使用Java語法編寫應(yīng)用程序,可以直接使用大部分的Java API等等。目前Dalvik VM隨著Android一起處于迅猛發(fā)展階段,在Android 2.2中已提供即時編譯器實現(xiàn),執(zhí)行性能有了很大的提高。
沒有成功,但并非失敗:Mircosoft JVM及其他
在十幾年的Java虛擬機發(fā)展歷程中,除去上面介紹那些被大規(guī)模商業(yè)應(yīng)用過的Java虛擬機外,還有許多虛擬機是不為人知或者曾經(jīng)絢麗過但最終湮滅的。我們以其中Mircorsoft公司的JVM來介紹一下。
也許Java程序員聽起來可能會覺得驚訝,微軟曾經(jīng)是Java技術(shù)的鐵桿支持者。在Java語言誕生的初期(1996年~1998年,以JDK1.2發(fā)布之前為分界),它的主要的應(yīng)用之一是在瀏覽器中運行Java Applets程序,微軟為了在IE3中支持Java Applets應(yīng)用而開發(fā)了自己的Java虛擬機,雖然這款虛擬機只有Windows平臺的版本(這很正常吧?),但卻是當時Windows下性能最好的Java虛擬機,它在1997和1998連續(xù)兩年獲得了《PC Magazine》雜志的“編輯選擇獎”。但好景不長,在1997年10月,Sun公司正式以侵犯商標、不正當競爭等罪名控告微軟,在隨后對微軟公司的壟斷調(diào)查之中,這款虛擬機也曾作為證據(jù)之一被呈送法庭。這場官司的結(jié)果是微軟賠償2000萬美金給Sun,承諾終止其Java虛擬機的發(fā)展,并逐步在產(chǎn)品中移除Java虛擬機相關(guān)功能。
我們試想一下,如果當年Sun沒有起訴微軟公司,微軟繼續(xù)保持著對Java技術(shù)的熱情,那Java的世界會變得更好還是更壞?.NET技術(shù)是否會發(fā)展起來?但歷史是沒有如果的。其他在本文中沒有介紹到的Java虛擬機還包括有(當然,應(yīng)該還有很多筆者所不知道的):
- JamVM:http://jamvm.sourceforge.net/
- cacaovm:http://www.cacaovm.org/
- SableVM:http://www.sablevm.org/
- Kaffe:http://www.kaffe.org/
- Jelatine JVM:http://jelatine.sourceforge.net/
- NanoVM:http://www.harbaum.org/till/nanovm/index.shtml
- MRP:http://mrp.codehaus.org/
- Moxie JVM:http://moxie.sourceforge.net/
- Jikes RVM:http://jikesrvm.org/
參考資料
本文撰寫時主要參考了以下資料:
- http://en.wikipedia.org/wiki/Java_virtual_machine
- http://wikis.sun.com/display/HotSpotInternals/Home
- http://rednaxelafx.iteye.com/blog/858009
?
[1] Sun與BEA分別在2010、2008年被Oracle公司收購,由于本文涉及到大量歷史事件,為了避免混亂,依然保留Sun和BEA的名稱。
?
總結(jié)
以上是生活随笔為你收集整理的Java虚拟机家族考的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java.awt.headless 模式
- 下一篇: Oracle数据库中序列(SEQUENC