深入理解 Java 虛擬機(一)走近 Java

1.1 - 概述

Java

總述:Java 不僅是一門編程語言,還是一個由一系列計算機軟件規(guī)范形成的技術(shù)體系,這個技術(shù)體系提供了完整的用于軟件開發(fā)和跨平臺部署的支持環(huán)境,并廣泛應用于

嵌入式系統(tǒng)。

移動終端 。

企業(yè)服務器 。

大型機等各種場合。

特點:Java 能獲得如此廣泛的認可,除了它擁有一門結(jié)構(gòu)嚴謹面向?qū)ο?/b>的編程語言之外,還有須有不可忽視的有點,主要有如下幾點??。

它擺脫了硬件平臺的束縛,實現(xiàn)了一次編寫,到處運行的越界問題。

它實現(xiàn)了熱點代碼檢測運行時編譯及優(yōu)化,這使得 Java 應用能隨著運行時間的增加而獲得更好的性能。

它有一套完善的應用程序接口,還有無數(shù)來自商業(yè)機構(gòu)合開源社區(qū)的第三方類庫來幫助它實現(xiàn)各種各樣的功能。

后面我們會一起學習 Java 技術(shù)中最重要的那些特性和實現(xiàn)原理,在本篇文章中,將會重點介紹 Java 技術(shù)體系內(nèi)容以及 Java 的歷史、現(xiàn)在和未來的發(fā)展趨勢。

1.2 - Java 技術(shù)體系

從廣義上講,Clojure、JRuby、Groovy 等運行于 Java 虛擬機上的語言及其相關(guān)的程序都屬于 Java 技術(shù)體系中的一員。如果僅從傳統(tǒng)意義上來看,Sun官方所定義的 Java 技術(shù)體系包括以下幾個組成部分??

Java 程序設計語言。

各種硬件平臺上的 Java 虛擬機。

Class 文件格式。

Java API 類庫。

來自商業(yè)機構(gòu)和開源社區(qū)的第三方 Java 類庫。

我們可以將Java 程序設計語言Java 虛擬機Java API類庫這三部分統(tǒng)稱為JDK(Java Development Kit),JDK 是用于支持 Java 程序開發(fā)的最小環(huán)境。另外,可以把 Java API 類庫中的 Java SE API 子集和 Java 虛擬機這兩部分統(tǒng)稱為JRE(Java Runtime Environment),JRE 是支持 Java 程序運行的標準環(huán)境。

JVM 結(jié)構(gòu)圖如下所示 ??

JVM 結(jié)構(gòu)圖

Java Language 體系圖如下所示 ??

Java Language

Java 技術(shù)體系可以分為4個平臺,分別是

Java Card:支持一些 Java 小程序(Applets)運行在小內(nèi)存設備(如智能卡)上的平臺。

JavaME(Micro Edition):支持 Java 程序運行在移動終端(手機、PDA)上的平臺。

JavaSE(Standard Edition):支持面向桌面級應用(如 Windows 下的應用程序)的 Java 平臺,提供了完整版的 Java 核心 API,這個版本以前也稱為 J2SE。

JavaEE(Enterprise Edition):支持使用多層架構(gòu)的企業(yè)應用(如 ERP、CRM 應用)的 Java 平臺,除了提供 JavaSE API 外,還對其做了大量的擴充并提供了相關(guān)的部署支持,這個版本以前稱為 J2EE。

1.3 - Java 發(fā)展史

從1996年 第一個 Java 版本誕生到現(xiàn)在已經(jīng)有了20幾年時間,其中誕生了無數(shù)和 Java 相關(guān)的產(chǎn)品、技術(shù)和標準,讓我們一同回顧下 Java 的發(fā)展軌跡和歷史變遷。

Java-version-history

1994-04:由James Gosling博士領導的綠色計劃(Green Project) 開始啟動,此計劃的目的是開發(fā)一種能夠在各種消費性電子產(chǎn)品(如機頂盒、冰箱、收音機等)上運行的程序架構(gòu)。這個計劃的產(chǎn)品就是 Java 語言的前身:Oak(橡樹)。Oak 當時在消費品市場上并不算成功,但隨著 1995 年互聯(lián)網(wǎng)潮流的興起,Oak 迅速找到了最適合自己發(fā)展的市場定位并蛻變成為 Java 語言。

1994-05-23:Oak 語言改名為 Java,并且在 SunWorld 大會上正式發(fā)布Java1.0版本。Java 語言第一次提出了Write Once, Run Anywhere的口號。

1996-01-23:JDK 1.0 發(fā)布,Java 語言有了第一個正式版本的運行環(huán)境。JDK 1.0 提供了一個純解釋執(zhí)行的 Java 虛擬機實現(xiàn)(Sun Classic VM)。JDK 1.0 版本的代表技術(shù)包括:(Java 虛擬機、Applet、AWT 等)。

1996-04:10個最主要的操作系統(tǒng)供應商申明將在其產(chǎn)品中嵌入 Java 技術(shù)。同年 9月,已有大約 8.3 萬個網(wǎng)頁應用了 Java 技術(shù)來制作。在 1996年5月底,Sun 公司于美國舊金山舉行了首屆 JavaOne 大會,從此 JavaOne 成為全世界數(shù)百萬 Java 語言開發(fā)者每年一度的技術(shù)盛會。

1997-02-19:Sun 公司發(fā)布了 JDK 1.1,Java 技術(shù)的一些最基礎的支撐點(JDBC等)都是在 JDK 1.1 版本中發(fā)布的,JDK 1.1版本的代表技術(shù)有(1.JAR 文件格式2.JDBC3.JavaBeans4.RMI)。Java 語法也有了一定的發(fā)展,如內(nèi)部類(Inner Class)和反射(Reflection) 都是在這個時候出現(xiàn)的。

1998-12-04:JDK 迎來了一個里程碑式的版本 JDK 1.2,工程代號為 Playground(競技場),Sun 在這個版本中把 Java 技術(shù)體系拆分為 3 個方向,分別是:

面向桌面應用開發(fā)的J2SE(Java 2 Platform,Standard Edition)

面向企業(yè)級開發(fā)的J2EE(Java 2 Platform,Enterprise Edition)

面向手機等移動端開發(fā)的J2ME(Java 2 Platform,Micro Edition)。

在這個版本中出現(xiàn)的代表性技術(shù)非常多(EJBJava Plug-inJava IDLSwing等),并且這個版本中 Java 虛擬機第一次內(nèi)置了JIT(Just In Time) 編譯器(JKD 1.2中曾并存過3個虛擬機,Classic VMHotSpot VMExact VM,其中 Exact VM 只能以外掛的形式使用 JIT 編譯器)。在語言和 API 級別上,Java 添加了strictfp關(guān)鍵字與現(xiàn)在 Java 編碼中極為常用的一系列Collection集合類。

1999-04-27:HotSpot虛擬機發(fā)布,HotSpot 最初由一家名為Longview Technologies的小公司開發(fā),因為其優(yōu)異的表現(xiàn),這家公司在 1997 年被 Sun 公司收購了。HotSpot 虛擬機發(fā)布時是作為 JDK 1.2的附加程序提供的,后來它成為了 JDK 1.3 及之后所有版本的 Sun JDK 的默認虛擬機。

2002-02-13:JDK 1.4發(fā)布,工程代號為 Merlin(灰背隼)。JDK 1.4 是 Java 真正走向成熟的一個版本,Compaq、Fujitsu、SAS、Symbian、IBM 等著名公司都有參與甚至實現(xiàn)自己獨立的 JDK 1.4。仍然有許多主流應用(Spring、Hibernate、Struts 等)能直接運行在 JDK 1.4 之上,或者繼續(xù)發(fā)布能運行在 JDK 1.4 上的版本。JDK 1.4 同樣發(fā)布了很多新的技術(shù)特性(正則表達式異常鏈NIO日志類XML解析器XSLT轉(zhuǎn)換器等)。

2004-09-30:JDK 1.5 發(fā)布(從這個版本開始官方正式文檔宣傳上已經(jīng)不再使用類似 JDK1.5的命名,只有在程序員內(nèi)部使用的開發(fā)版本號,例如java -version的輸出,而公開版本號則改為 JDK 5),工程代號 Tiger(老虎)。從 JDK 1.2 以來,Java 在語法層面上的變換一直很小,而 JDK 1.5 在 Java 語法易用性上做出了非常大的改進。例如(自動裝箱泛型動態(tài)注釋枚舉可變長參數(shù)foreach循環(huán)等)語法特性都是在 JDK 1.5 中加入的。在虛擬機和 API 層面上,這個版本改進了 Java 的內(nèi)存模型(Java Memory Model, JVM)、提供了java.util.concurrent并發(fā)包等。

2006-12-11:JDK 1.6 發(fā)布,工程代號 Mustang(野馬)。在這個版本中 Sun 終結(jié)了 JDK 1.2 開始已經(jīng)有8年歷史的 J2EE、J2SE、J2ME 的命名方式,啟用Java SE 6、Java EE 6、Java ME 6的命名方式。JDK 1.6 的改進包括:提供動態(tài)語言支持(通過內(nèi)置 Mozilla JavaScript Rhino 引擎實現(xiàn))、提供編譯 API 和微型 HTTP 服務器 API 等。同時,這個版本對 Java 虛擬機內(nèi)部做了大量改進,包括鎖與同步垃圾回收類加載等方面的算法都有相當多的改動。

2006-11-13:JavaOne 大會上,Sun 公司宣布最終會將 Java 開源,并在隨后的一年多時間內(nèi),陸續(xù)將 JDK 的各個部分在 GPL v2(GNU General Public License v2)協(xié)議下公開了源碼,并建立了 OpenJDK 組織對這些源碼進行獨立管理。除了極少量的產(chǎn)權(quán)代碼(Encumbered Code,這部分代碼大多是 Sun 本身也無權(quán)限進行開源處理的)外,OpenJDK 幾乎包括了 Sun JDK 的全部代碼,OpenJDK 的質(zhì)量主管曾經(jīng)表示,在 JDK 1.7 中,Sun JDK 和 OpenJDK 除了代碼文件頭的版權(quán)注釋之外,代碼基本上完全一樣,所以 OpenJDK 7 與 Sun JDK 1.7 本質(zhì)上就是同一套代碼庫開發(fā)的產(chǎn)品。

JDK 1.6 發(fā)布以后,由于代碼復雜性的增加、JDK 開源、開發(fā) JavaFX、經(jīng)濟危機及 Sun 收購案等原因,Sun 在 JDK 發(fā)展以外的事情上耗費了很多資源,JDK 的更新并沒有再維持兩年發(fā)布一個版本的發(fā)展速度??。

2009-02-19:工程代號為 Dolphin(海豚)的 JDK 1.7 完成了其第一個里程碑版本。根據(jù) JDK 1.7 的功能規(guī)劃,一共設置了10個里程碑。最后一個里程碑版本原計劃與 2010 年 9 月 9 日技術(shù),但由于各種原因,JDK 1.7 最終無法按計劃完成。

從 JDK 1.7 最開始的功能規(guī)劃來看,它本應是一個包含許多重要改進的 JDK 版本,其中 Lambda 項目(Lambda表達式函數(shù)式編程)、Jigsaw項目(虛擬機模塊化支持)、動態(tài)語言支持GarbageFirst收集器Coin項目(語言細節(jié)進化)等子項目對于 Java 業(yè)界都會產(chǎn)生深遠的影響。在 JDK 1.7 開發(fā)期間,Sun 公司由于相繼在技術(shù)競爭和商業(yè)競爭中都陷入泥潭,公司的股票市值跌至僅有高峰時期的 3%??(心疼),已無力推動 JDK 1.7 的研發(fā)工作按正常計劃進行。為了盡快結(jié)束 JDK 1.7 長期 ”跳票” 的問題,Oracle 公司收購 Sun 公司后不久便宣布將實行 “B計劃”,大幅裁剪了 JDK 1.7 預訂目標,以便保證 JDK 1.7 的正式版能夠與 2011年7月28日準時發(fā)布。”B計劃” 把不能按時完成的 Lambda 項目、Jigsaw 項目和 Coin 項目的部分改進延遲到 JDK 1.8之中。最終,JDK 1.7 的主要改進包括:提供新的G1收集器加強對非 Java 語言的調(diào)用支持升級類加載架構(gòu)等。

2009-04-20:Oracle 公司宣布正式以74億美元的價格收購 Sun 公司,Java 商標從此正式歸 Oracle 所有(Java 語言本身并不屬于哪家公司所有,它由 JCP 組織進行管理,盡管 JCP 主要是由 Sun 公司或者說 Oracle 公司所領導的)。由于此前 Oracle 公司已經(jīng)收購了另外一家大型的中間件企業(yè) BEA 公司,在完成對 Sun 公司的收購之后,Oracle 公司分別從BEASun中取得了目前三大商業(yè)虛擬機其中兩個:JRockitHotSpot,Oracle 公司宣布在未來的 1-2年的時間內(nèi),將把這兩個優(yōu)秀的虛擬機相互取長補短,最終合二為一。

在 2011年的 JavaOne 大會上,Oracle 公司還提到了 JDK 1.9 的長遠規(guī)劃,希望未來的 Java 虛擬機能夠管理數(shù)以 GB 計的 Java 堆??,能夠更高效地與本地代碼繼承,并且令 Java 虛擬機運行時盡可能少人工干預,能夠自動調(diào)節(jié)。

1.4 - Java 虛擬機發(fā)展史

上一節(jié)從整個 Java 技術(shù)的角度觀察了 Java 技術(shù)的發(fā)展,許多 Java 程序員都會潛意識地把它與 Sun 公司的 HotSpot 虛擬機等同看待,也許還有一些人會注意到BEA JRockitIBM J9,但對 JVM 的認識不僅僅只有這些。

從 1996 年初 Sun 公司發(fā)布的 JDK 1.0 中所包含的Sun Classic VM到今天,曾經(jīng)涌現(xiàn)、湮滅過許多經(jīng)典或優(yōu)秀或有特色的虛擬機實現(xiàn),在這一節(jié)中我們一起來回顧一下 Java 虛擬機家族的發(fā)展軌跡和歷史變遷。

1.4.1 - Sun Classic / Exact VM

從今天的視角來看,Sun Classic VM的技術(shù)可能很原始,這款虛擬機的使命也早已終結(jié)。但僅憑它世界上第一款商用 Java 虛擬機的頭銜,就足夠有讓歷史記住它的理由??。

1996-01-23:Sun 公司發(fā)布 JDK 1.0,Java 語言首次擁有了商用的正式運行環(huán)境,這個 JDK 中所帶的虛擬機就是 Classic VM。這款虛擬機只能使用純解釋器方式來執(zhí)行 Java 代碼,如果要使用 JIT 編譯器,就必須進行外掛。但是加入外掛了 JIT 編譯器,JIT 編譯器就完全接管了虛擬機的執(zhí)行系統(tǒng),解釋器便不再工作了。用戶在這款虛擬機上執(zhí)行java -version命令,將會看到類似下面這行輸出

javaversion"1.2.2"ClassicVM(buildJDK-1.2.2-001,greenthreads,sunwjit)

其中的sunwjit就是 Sun 提供的外掛編譯器,其他類似的外掛編譯器還有Symantec JITshuJIT等。由于解釋器編譯器不能配合工作,這就意味著如果要使用編譯器執(zhí)行,編譯器就不得不對每一個方法、每一行代碼都進行編譯,而無論他們執(zhí)行的頻率是否具有編譯的價值。基于程序響應時間的壓力,這些編譯器根本不敢應用編譯耗時稍高的優(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)而得名,即虛擬機可以知道內(nèi)存中某個位置的數(shù)據(jù)具體是什么類型。例如內(nèi)存中有一個 32 位的整數(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 的,所以要使用句柄來保持 refrence 值的穩(wěn)定),這樣每次定位對象都少了一次間接查找的開銷,提升執(zhí)行性能。

雖然Exact VM的技術(shù)相對Classic VM來說先進了許多,但是在商業(yè)應用上只存在了很短暫的時間就被更為優(yōu)秀的HotSpot VM所取代,甚至還沒有來得及發(fā)布 Windows 和 Linux 平臺下的商用版本。而 Classic VM 的生命周期則相對長了許多,它在 JDK 1.2 之前是 Sun JDK 中唯一的虛擬機,在 JDK 1.2時,它與 HotSpot VM 并存,但默認使用的是 Classic VM,而在 JDK 1.3 時,HotSopt VM 成為默認虛擬機,但 Classic VM 仍作為虛擬機的 “備用選擇” 發(fā)布,直到 JDK 1.4 的時候,Classic VM 才完全退出商用虛擬機的歷史舞臺,與 Exact VM 一起進入了Sun Labs Research VM中 ??。

1.4.2 - Sun HotSpot VM

提起HotSpot VM,相信所有 Java 程序員都知道,它是 Sun JDK 和 OpenJDK 中所帶的虛擬機,也是目前使用范圍最廣的 Java 虛擬機。但不一定所有人都知道的是,這個目前看來 ”血統(tǒng)純正” 的虛擬機在最初并非由 Sun 公司開發(fā),而是一家名為Longview Technologies的小公司設計的;設置這個虛擬機最初并非是為 Java 語言而開發(fā)的,它來源于Strongtalk VM,而這款虛擬機中相當多的技術(shù)又是來源于一款 Self 語言實現(xiàn) “可能達到 C 語言 50% 以上的執(zhí)行效率” 的目標而設計的虛擬機,Sun 公司注意到了這款虛擬機在 JIT 編譯上有許多優(yōu)秀的理念和實際效果,在 1997 年收購了Longview Technologies公司,從而獲得了 HotSpot VM。

HotSpot VM 繼承了 Sun 之前兩款商用虛擬機的優(yōu)點 =>準確式內(nèi)存管理,也有許多自己新的技術(shù)優(yōu)勢,如它名稱中的 HotSpot 指的就是它的熱點代碼探測技術(shù)(其實兩個 VM 基本上是同時期的獨立產(chǎn)品,HotSpot 還稍早一些,HotSpot 一開始就是準確式 GC,而Exact VM中也有與之幾乎一樣的熱點探測。為了 Exact VM 和 HotSpot VM 哪個成為 Sun 主要支持的 VM 產(chǎn)品,在 Sun 公司內(nèi)部還有過爭論,HotSpot 打敗 Exact 并不能算技術(shù)上的勝利),HotSpot VM 的熱點代碼探測能力可以通過執(zhí)行計數(shù)器找出最具有編譯價值的代碼,然后通知 JIT 編譯器以方法為單位進行編譯。如果一個方法被頻繁調(diào)用,或方法中有效循環(huán)次數(shù)很多,將會被分別觸發(fā)標準編譯OSR(棧上替換)編譯動作。通過編譯器與解釋器恰當?shù)貐f(xié)同工作,可以在最優(yōu)化的程序相應時間與最佳執(zhí)行性能中取得平衡,而且無須等待本地代碼輸出才能執(zhí)行程序,即時編譯的時間壓力也相對減小,這樣有助于引入更多的代碼優(yōu)化技術(shù),輸出質(zhì)量更高的本地代碼。

在 2006 年的 JavaOne 大會上,Sun 公司宣布最終會把 Java 開源,并在隨后的一年,陸續(xù)將 JDK 的各個部分(其中當然也包括了 HotSpot VM)在 GPL 協(xié)議下公開了源碼,并在此基礎上建立了 OpenJDK。這樣,HotSpot VM 便成為了 Sun JDK 和 OpenJDK 兩個實現(xiàn)極度接近的 JDK 項目的共同虛擬機。

1.4.3 - Sun Mobile-Embedded VM / Meta-Circular VM

Sun 公司所研發(fā)的虛擬機可不僅有前面介紹的服務器、桌面領域的商用虛擬機,除此之外,Sun 公司面對移動嵌入式市場,也發(fā)布過虛擬機產(chǎn)品,另外還有一類虛擬機,在設計之初就沒報有商用目的,僅僅是用于研究、驗證某種技術(shù)和觀點,又或者是作為一些規(guī)范的標準實現(xiàn)。這些虛擬機對于大部分不從事相關(guān)領域開發(fā)的 Java 程序員來說可能比較陌生,Sun 公司發(fā)布的其他 Java 虛擬機有

KVM:K 是 Kilobyte 的意思,它強調(diào)簡單、輕量、高度可移植,但是運行速度比較慢。在 Android、iOS 等智能手機操作系統(tǒng)出現(xiàn)前曾經(jīng)在手機平臺上得到非常廣泛的應用。

CDC/CLDC HotSpot Implementation:CDC/CLDC全稱是 Connected(Limited)Device Configuration,在 JSR-136、JSR-218 規(guī)范中進行定義,它希望在手機、電子書、PDA 等設備上建立統(tǒng)一的 Java 編程接口,而CDC-HI VMCLDC-HI VM則是它們的一組參考實現(xiàn)。CDC/CLDC 是整個JavaME的重要支柱,但從目前 Android 和 iOS 二分天下的移動數(shù)字設備市場看來,在這個領域中,Sun 的虛擬機所面臨的局面遠不如服務器和桌面領域樂觀。

Squawk VM:Squawk VM 由 Sun 公司開發(fā),運行于 Sun SPOT(Sun Small Programmable Object Technology,一種手持的 WiFi 設備),也曾經(jīng)運用于 Java Card。這是一個 Java 代碼比重很高的嵌入式虛擬機實現(xiàn),其中諸如類加載器、字節(jié)碼驗證器、垃圾回收器、解釋器、編譯器和線程調(diào)度都是 Java 語言本身完成的,僅僅靠 C 語言來編寫設備 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í)行。在 20世紀末主流 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 的水平。

1.4.4 BEA JRockit / IBM J9 VM

前面介紹了 Sun 公司的各種虛擬機,除了 Sun 公司以外,其他組織、公司也研發(fā)過不少虛擬機實現(xiàn),其中規(guī)模最大、最著名的就是BEAIBM公司了。

JRockit VM 曾經(jīng)號稱世界上速度最快的 Java 虛擬機(廣告詞,貌似 J9 VM 也這樣說過??),它是 BEA 公司在 2002 年從Appeal Virtual Machines公司收購的虛擬機。BEA 公司將其發(fā)展為一款專門為服務器硬件和服務器端應用場景高度優(yōu)化的虛擬機,由于專注于服務器端應用,它可以不太關(guān)注程序啟動速度,因此 JRockit 內(nèi)部不包含解析器實現(xiàn),全部代碼都靠即時編譯器編譯后執(zhí)行。除此之外,JRockit 的垃圾收集器和MissionControl服務套件等部分的實現(xiàn),在眾多 Java 虛擬機中也一直處于領先水平。

IBM J9 VM 并不是 IBM 公司唯一個 Java 虛擬機,不過是目前其主力發(fā)展的 Java 虛擬機。IBM J9 VM 原本是內(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 專注于服務器端應用不同,IBM J9 的市場定位與 Sun HotSpot 比較接近,它是一款設計上從服務器端到桌面應用再到嵌入式都全面考慮的多用途虛擬機,J9 的開發(fā)目的是做為 IBM 公司各種 Java 產(chǎn)品的執(zhí)行平臺,它的主要市場是和 IBM 產(chǎn)品(如 IBM WebSphere 等)搭配以及在 IBM AIX 和 z/OS 這些平臺上部署 Java 應用。

1.4.5 - Azul VM / BEA Liquid VM

我們平時所提及的 “高性能 Java 虛擬機”,一般是指 HotSpot、JRockit、J9這類在通用平臺上運行的商用虛擬機,但其實Azul VMBEA Liquid VM這類特定硬件平臺專有的虛擬機才是高性能的武器。

Azul VM 是 Azul Systems 公司在 HotSpot 基礎上進行大量改進,運行于 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 System 公司開始從硬件轉(zhuǎn)向軟件,發(fā)布了自己的 Zing JVM,可以在通用的 x86 平臺上提供接近于 Vega 系統(tǒng)的特性。

Liquid VM 即是現(xiàn)在的 JRockit VM 虛擬化版本,Liquid VM 不需要操作系統(tǒng)的支持,或者說它自己本身實現(xiàn)了一個專有操作系統(tǒng)的必要功能,如文件系統(tǒng)、網(wǎng)絡操作等。由虛擬機越過通用操作系統(tǒng)直接控制硬件可以獲得很多好處,如在線程調(diào)度時,不需要再進行內(nèi)核態(tài) / 用戶態(tài)的切換等,這樣可以最大限度地發(fā)揮硬件的功能,提升 Java 程序的執(zhí)行性能。

1.4.6 - Apache Harmony / Google Android Dalvik VM

這節(jié)介紹的兩個虛擬機只能稱作 “虛擬機”,而不能稱做 “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 基金會曾經(jīng)要求 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 沒有經(jīng)歷過真正大規(guī)模的商業(yè)運作,但是它的許多代碼(基本上是 Java 庫部分的代碼)被吸納進 IBM 的 JDK7 實現(xiàn)及 Google Android SDK 之中,尤其是對 Android 的發(fā)展起到了很大的推動作用。

說到 Android,這個時下最熱門的移動數(shù)碼設備平臺在最近幾年間的發(fā)展過程中所取得的成果已經(jīng)遠遠超越了 Java ME 在過去十多年所取得的成果,Android 讓 Java 語言真正走進了移動數(shù)碼設備領域,只是走的并非 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 語法編寫應用程序,可以直接使用大部分的 Java API 等。目前 Dalvik VM 隨著 Android 一起處于一個迅猛發(fā)展階段,在 Android 2.2 中已提供即時編譯器實現(xiàn),在執(zhí)行性能上有了很大的提高。

1.4.7 - Microsoft JVM 及其他

在十幾年的 Java 虛擬機發(fā)展過程中,除去上面介紹而那些被大規(guī)模商業(yè)應用過的 Java 虛擬機外,還有許多虛擬機是不為人知的或者曾經(jīng) “絢麗” 過但最終湮滅的。我們以其中微軟公司的 JVM 為例來介紹一下。

也許 Java 程序員聽起來可能會覺得驚訝,微軟公司曾經(jīng)是 Java 技術(shù)的鐵桿支持者(也必須承認,與 Sun 公司爭奪 Java 控制權(quán),令 Java 從跨平臺技術(shù)變?yōu)榻壎ㄔ?Windows 上的技術(shù)是微軟公司的主要目的)。在 Java 語言誕生初期(1996年-1998年,以 JDK1.2 發(fā)布為界),它的主要應用之一是在瀏覽器中運行 Java Applets 程序,微軟公司為了在 IE3 中支持Java Applets應用而開發(fā)了自己的 Java 虛擬機,雖然這款虛擬機只有 Windows 平臺的版本,卻是當時 Windows 下性能最好的 Java 虛擬機,它在 1997年和1998年連續(xù)兩年獲得了《PC Magazine》雜志的 “編輯選擇獎”。但好景不長,在 1997年10月,Sun 公司正式以侵犯商標、不正當競爭等罪名控告微軟公司,在隨后對微軟公司的壟斷調(diào)查之中,這款虛擬機也曾經(jīng)作為證據(jù)之一被呈送法庭。這場官司的結(jié)果是微軟公司賠償 2000 萬美金給 Sun 公司(最終微軟公司因壟斷賠償給 Sun 公司的總金額高達 10 億美元),承諾終止其 Java 虛擬機的發(fā)展,并逐步在產(chǎn)品中移除 Java 虛擬機相關(guān)功能。具有諷刺意味的是,在最后 Windows XP SP3 中 Java 虛擬機被完全抹去的時候,Sun 公司卻又到處登報希望微軟公司不要這樣做。Windows XP 高級產(chǎn)品經(jīng)理 Jim Cullinan 稱:”我們花了 3 年時間和 Sun 打官司,當時他們試圖阻止我們在 Windows 中支持 Java,現(xiàn)在我們這樣做了,可他們又在抱怨,這太具有諷刺意味了。”

如果當前 Sun 公司沒有起訴微軟公司,微軟公司繼續(xù)保持對 Java 技術(shù)的熱情,那 Java 的世界會變得怎么樣呢?.NET 技術(shù)是否會發(fā)展起來?但歷史是沒有假設的。還有一些 Java 虛擬機是沒有介紹到的。

1.5 - 展望 Java 技術(shù)的未來

在 2005 年,Java 技術(shù)誕生 10 周年的 SunOne 技術(shù)大會上,Java 語言之父 James Gosling 做了一場題為 “Java 技術(shù)下一個十年” 的演講。筆者不具備 James Gosling 博士那樣高屋建瓴的視角,這里僅從 Java 平臺中幾個新生的但已經(jīng)開始展現(xiàn)出蓬勃之勢的技術(shù)發(fā)展點來看一下后續(xù) JDK 版本的一些很有希望的技術(shù)重點。

1.5.1 - 模塊化

模塊化是解決應用系統(tǒng)與技術(shù)平臺越來越服復雜、越來越龐大問題的一個重要途徑。無論是開發(fā)人員還是產(chǎn)品最終用戶,都不希望為了系統(tǒng)中一小塊的功能而不得不下載、安裝、部署及維護整套龐大的系統(tǒng)。站在整個軟件工業(yè)化的高度來看,模塊化是建立各種功能的標準件的前提。最近幾年 OSGi 技術(shù)的迅速發(fā)展、各個廠商在 JCP 中對模塊化規(guī)范的激烈斗爭,都能充分說明模塊化技術(shù)的迫切和重要。

在未來的 Java 平臺中,很可能會對模塊化提出語法層面的支持。早在 2007 年,Sun 公司就提出過 JSR-277:Java 模塊系統(tǒng)(Java Module System),試圖建立 Java 平臺的模塊化標準,但受挫于以 IBM 公司為主導提交的 JSR-291:Java SE 動態(tài)組件支持(Dynamic Component Support for Java SE,這實際就是 OSGi R4.1)。由于模塊化規(guī)范主導權(quán)的重要性,Sun 公司不能接受一個無法由它控制的規(guī)范,Sun 公司再次提交了一個新的規(guī)范請求文檔 JSR-294:Java 編程語言中的改進模塊性支持(Improved Modularity Support in the Java Programming Language),盡管這個 JSR 仍然沒有通過,但是 Sun 公司已經(jīng)獨立于 JCP 專家組在 OpenJDK 里建立了一個名為 Jigsaw(拼圖)的子項目來推動這個規(guī)范在 Java 平臺中轉(zhuǎn)變?yōu)榫唧w的實現(xiàn)。Java 模塊化之爭目前還沒有結(jié)束,OSGi 已經(jīng)發(fā)布到 R5.0 版本,而 Jigsaw 從 Java 7 延遲至 Java 8,在 2012 年 7 月又不得不宣布推遲到 Java9 中發(fā)布,從這點看來,Sun 在這場戰(zhàn)爭中處于劣勢,但無論勝利者是哪一方,Java 模塊化已經(jīng)成為一項無法阻擋的變革潮流。

1.5.2 - 混合語言

當單一的 Java 開發(fā)已經(jīng)無法滿足當前軟件的復雜需求時,越來越多基于 Java 虛擬機的語言開發(fā)被應用到軟件項目中,Java 平臺上的多語言混合編程正成為為主流,每種語言都可以針對自己擅長的方面更好地解決問題。試想一下,在一個項目之中,并行處理用 Clojure 語言編寫,展示層使用 JRuby / Rails,中間層則是 Java,每個應用層都將使用不同的編程語言來完成,而且,接口對每一層的開發(fā)者都是透明的,各種語言之間的交互不存在任何困難,就像使用自己語言的原生 API 一樣方便,因為它們最終都運行在一個虛擬機之上。

在最近的幾年里,Clojure、JRuby、Groovy 等新生語言的使用人數(shù)不斷增長,而運行在 Java 虛擬機(JVM)之上的語言數(shù)量也在迅速膨脹。通過特定領域的語言去解決特定領域的問題是當前軟件開發(fā)應對日趨復雜的項目需求的一個方向。

Languages In The Java

除了催生出大量的新語言外,許多已經(jīng)有很長歷史的程序語言也出現(xiàn)了基于 Java 虛擬機實現(xiàn)的版本,這樣使得混合編程對許多以前使用其他語言的 “老” 程序員也具備相當大的吸引力,軟件企業(yè)投入了大量資本的現(xiàn)有代碼資產(chǎn)也能很好地保護起來。

1.5.3 - 多核并行

如今,CPU 硬件的發(fā)展方向已經(jīng)從高頻率轉(zhuǎn)變?yōu)?b>多核心,隨著多核時代的來臨,軟件開發(fā)越來越關(guān)注并行編程的領域。早在 JDK1.5 就已經(jīng)引入java.util.concurrent包實現(xiàn)了一個粗粒度的并發(fā)框架。而 JDK1.7 中加入的java.util.cuncurrent.forkjoin包則是對這個框架的一次重要擴充。Fork / Join模式是處理并行編程的一個經(jīng)典方法。雖然不能解決所有的問題,但是在此模式的適用范圍之內(nèi),能夠輕松地利用多個 CPU 核心提供的計算資源來協(xié)作完成一個復雜的計算任務。通過利用 Fork / Join 模式,我們能夠更加順場地過渡到多核心時代。

Fork / Join 模式

在 Java 8 中,將會提供Lambda支持,這將會極大改善目前 Java 語言不適合函數(shù)式編程的現(xiàn)狀(目前 Java 語言使用函數(shù)式編程并不是不可以,只是會顯得很臃腫),函數(shù)式編程的一個重要優(yōu)點就是這樣的程序天然地適合并行運行,這對 Java 語言在多核時代繼續(xù)保持主流語言的地位有很大幫助。

另外,在并行計算中必須提及的還有 OpenJDK 的子項目Sumatra,目前顯卡的算術(shù)運算能力、并行能力已經(jīng)遠遠超過了 CPU,在圖形領域以發(fā)掘顯卡的潛力是近幾年計算機發(fā)展的方向之一,例如 C 語言的 CUDA。Sumatra 項目就是為 Java 提供使用GPU(Graphics Processing Units)和APU(Accelerated Processing Units) 運算能力的工具,以后它將會直接提供 Java 語言層面的 API,或者為 Lambda 和其他 JVM 語言提供底層的并行運算支持。

在 JDK 外圍,也出現(xiàn)了專為滿足并行計算需求的計算框架,如 Apache 的 Hadoop Map / Reduce,這是一個簡單易懂的并行框架,能夠運行在由上千個商用機器組成的大型集群上,并且能以一種可靠的容錯方式并行處理 TB 級別的數(shù)據(jù)集。另外,還出現(xiàn)了諸如 Scala、Clojure 及 Erlang 等天生就具備并行計算能力的語言。

1.5.4 - 進一步豐富語法

Java 5 曾經(jīng)對 Java 語法進行了一次擴充,這次擴充加入了自動裝箱泛型動態(tài)注解枚舉可邊長參數(shù)遍歷循環(huán)等語法,使得 Java 語言的精確性和易用性有了很大的進步。在 Java 7(由于進度壓力,許多改進已推遲至 Java 8)中,對 Java 語言進行了另一次大規(guī)模的擴充。Sun(以被 Oracle 收購)專門為改進 Java 語法在 OpenJDK 中建立了 Coin 子項目來統(tǒng)一處理對 Java 語法的細節(jié)修改,如二進制數(shù)的原生支持、在 switch 語句中支持字符串、<>等操作符、異常處理的改進、簡化變長參數(shù)方法調(diào)用、面向資源的try-catch-finally語句等都是在 Coin 項目之中提交的內(nèi)容。

除了 Coin 項目之外,在 JSR-355(Lambda Expressions for the Java TM Programming Language)中定義的 Lambda 表達式也將對 Java 的語法和語言習慣產(chǎn)生很大的影響,面向函數(shù)方式的編程可能會成為主流。

1.5.5 - 64位虛擬機

在幾年之前,主流的 CPU 就開始支持 64 位架構(gòu)了。Java 虛擬機也是在很早之前就退出了支持 64 位系統(tǒng)的版本。但 Java 程序運行在 64 位虛擬機上需要付出比較大的額外代價:首先是內(nèi)存問題,由于指針膨脹和各種數(shù)據(jù)類型對齊補白的原因,運行于 64 位系統(tǒng)上的 Java 應用需要消耗更多的內(nèi)存,通常要比 32 位系統(tǒng)額外增加 10%-30% 的內(nèi)存消耗;其次,多個機構(gòu)的測試結(jié)果顯示,64 位虛擬機的運行速度在各個測試項中幾乎全面落后于 32 位虛擬機,兩者大約有 15% 左右的性能差距。

但是在 Java EE 方面,企業(yè)級應用經(jīng)常需要使用超過 4GB 的內(nèi)存,對于 64 位虛擬機的需求是非常迫切的,但由于上述原因,許多企業(yè)應用仍然選擇使用虛擬集群等方式繼續(xù)在 32 位虛擬機中進行部署。Sun 也注意到了這些問題,并做出了一些改善,在 JDK 1.6 Update14 之后,提供了普通對象指針壓縮同能(-XX:+ UseCompressedOops,這個參數(shù)不建議顯示設置,建議維持默認由虛擬機的 Ergonomics 機制自動開啟),在執(zhí)行代碼時,動態(tài)植入壓縮指令以節(jié)省內(nèi)存消耗,但是開啟壓縮指針會增加執(zhí)行代碼數(shù)量,因為所有在 Java 堆里的、指向 Java 堆對象的指針都會被壓縮,這些指針的訪問就需要更多的代碼才可以實現(xiàn),并且并不只是讀寫字段才受影響,在實例方法調(diào)用、子類型檢查等操作中也受影響,因為對象實例的引用也被壓縮了。隨著硬件的進一步發(fā)展,計算機終究會完全過渡到 64 位的時代,這是一件毫無疑問的事情,主流的虛擬機應用也終究會從 32 位發(fā)展至 64 位,而虛擬機對 64 位的支持也將會進一步完善。

喜歡小編輕輕點個關(guān)注哦!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內(nèi)容