1. 程式人生 > >[連載] 深入理解Java虛擬機器(JVM高階特性與最佳實踐)之 【走近Java】

[連載] 深入理解Java虛擬機器(JVM高階特性與最佳實踐)之 【走近Java】

連載目錄 :    http://blog.csdn.net/u010903284/article/details/53117958

1.1 Java概述:
              Java 不僅僅是一門程式語言,還是一個由一系列計算機軟體和規範形成的技術體系,這個技術體系提花了完整的用於軟體開發的和平臺部署的環境,並廣泛應用於嵌入式系統,移動終端,企業伺服器,大型機等各種場合。

1.2 Java技術體系
1、從廣義上分={

                 a:Java程式設計語言;

                 b:各種硬體平臺上的Java虛擬機器;

                 c:Class檔案格式;

                 d:來自商業機構和開源社群的第三方Java類庫

              }
2、按照組成部分的功能分={a:java se; b:java ee;c:java me;}

1.3 java發展史
1.4 Java虛擬機發展史


    1.4.1 : Sun classic / Exact VM

             JDK1.0所帶的虛擬機器就是Classic VM:這款虛擬機器只能使用純直譯器方式來執行Java程式碼。如果要使用JIT編譯器,就必須進行外掛。但是假 如外掛了JIT編譯器,JIT編譯器就完全接管了虛擬機器的執行系統,直譯器便不再工作了。由於直譯器和編譯器不能配合工作,這就意味著如果要使用編譯器執行,編譯器就不得不對每一個方法,每一行程式碼都進行編譯,而無論它們執行的頻率是否具有編譯價值。基於程式響應時間的壓力,這些編譯器根本不敢應用編譯耗時稍高的優化技術。基於handler的物件查詢方式,使用控制代碼來保持reference值的穩定。


    1.4.2 : Sun HotSpot VM

             JDK1.3所帶的虛擬機器就是HotSpot VM:HotSpot指的就是它的熱點程式碼探測技術。HotSpot VM的熱點程式碼探測能力可以通過執行計數器找出最具有編譯價值的程式碼,然後通過JIT編譯器以方法為單位進行編譯。如果一個方法被頻繁呼叫,或方法中有效迴圈次數很多,將會分別觸發標準編譯和OSR(棧上替換)編譯動作。通過編譯器和直譯器恰當地協同工作,可以在最優化的程式響應時間與最佳執行效能中取得平衡,而且無須等待原生代碼輸出才能執行程式,即時編譯的時間壓力也相對減小,這樣有助於引入更多的程式碼優化技術,輸出質量更高的原生代碼。


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

Sun公司所研發的虛擬機器可不僅有前面介紹的伺服器、桌面領域的商用虛擬機器,除此之外,Sun公司面對移動和嵌入式市場,也釋出過虛擬機器產品,另外還有一類虛擬機器,在設計之初就沒抱有商用的目的,僅僅是用於研究、驗證某種技術和觀點,又或者是作為一些規範的標準實現。這些虛擬機器對於大部分不從事相關領域開發的Java程式設計師來說可能比較陌生。Sun公司釋出的其他Java虛擬機器有:

(1)KVM

KVM中的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 VM

Maxine VM和上面的JavaInJava非常相似,它也是一個幾乎全部以Java程式碼實現(只有用於啟動JVM的載入器使用C語言編寫)的元迴圈Java虛擬機器。這個專案於2005年開始,到現在仍然在發展之中,比起JavaInJava,Maxine VM就顯得“靠譜”很多,它有先進的JIT編譯器和垃圾收集器(但沒有直譯器),可在宿主模式或獨立模式下執行,其執行效率已經接近了HotSpot Client VM的水平。


    1.4.4 : 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應用。


    1.4.5 : 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程式的執行效能。

    1.4.6 : 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中已提供即時編譯器實現,在執行效能上有了很大的提高。


    1.4.7 : 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,現在我們這樣做了,可他們又在抱怨,這太具有諷刺意味了。”

我們試想一下,如果當年Sun公司沒有起訴微軟公司,微軟公司繼續保持著對Java技術的熱情,那Java的世界會變得怎麼樣呢?.NET技術是否會發展起來?但歷史是沒有假設的。其他在本節中沒有介紹到的Java虛擬機器還有(當然,應該還有很多筆者所不知道的):

JamVM。

cacaovm。

SableVM。

Kaffe。

Jelatine JVM。

NanoVM。

MRP。

Moxie JVM。

Jikes RVM。

【相關筆記--怎麼檢視當前虛擬機器的版本】

執行cmd命令列 —> 輸入  java -version  —> 回車檢視JVM版本



1.5展望Java技術的未來

1.5.1 模組化

      模組化是解決應用系統與技術平臺越來越複雜,越來越龐大問題的一個重要途徑。Java模組化已經成為一項無法阻擋的變革潮流。


1.5.2 混合語言

     Java平臺上的多語言混合程式設計正成為主流,每種語言都可以針對自己擅長的方面更好地解決問題。試想一下,並行處理用Clojure語言編寫,展示層使用JRuby/Rails,中間層使用Java,每個應用層都將使用不同的程式語言來完成,而且,介面對每一層的開發者都是透明的,各種語言之間的互動不存在任何困難,就像使用自己語言的原生API一樣方便。因為它們最終都執行在一個虛擬機器之上。


1.5.3 多核並行

     並行程式設計領域,早在JDK1.5就已經引入java.util.concurrent包實現了一個粗粒度的併發框架。而JDK1.7中加入的java.util.concurrent.forkjoin包則是對這個框架的一次重要擴充。Fork/Join模式是處理並行程式設計的一個經典方法,在此模式的使用範圍之內,能夠輕鬆地利用多個CPU核心提供的計算資源來協作完成一個複雜的計算任務。通過Fork/Join模式,我們能夠順暢地過渡到多核時代。

在Java 8中,將會提供Lambda支援,函數語言程式設計的一個重要優點就是這樣的程式天然地適合並行執行,這對Java語言在多核時代繼續保持主流語言的地位很有幫助。


1.5.4 進一步豐富語法

      Java 5 曾經對Java語法進行了一次擴充,這次擴充加入了自動裝箱,泛型,動態註解,列舉,可變長引數,遍歷迴圈等語法,使得Java語言的精確性和可用性有了很大的進步,Java7(由於進度壓力,許多改進已推遲至Java 8 ) 中,對Java語法進行了另一次大規模的擴充,Sun(已被Oracle收購)專門為改進Java語法在OpenJDK中建立了Coin子專案來統一處理對Java語法的細節修改。Java語法越來越豐富有我們的眼皮底下進行著。


1.5.5 64位虛擬機器

     Java程式執行在64位虛擬機器上需要付出比較大的額外代價:(1)首先是記憶體問題,由於指標膨脹和各種資料型別對齊補白的原因,運行於64位系統上的Java應用需要消耗更多的記憶體,通常要比32位系統額外增加10%~30%的記憶體消耗;(2)其次是效能問題,多個機構的測試結果顯示,64位虛擬機器的執行速度在各個測試項中幾乎全面落後於32位虛擬機器,兩者大約有15%左右的效能差距。

面對以上問題,Sun給出的解決方案:在JDK 1.6 Update 14之後,提供了普通物件指標壓縮功能(-XX:+UseCompressedOops,這個引數不建議顯示設定,建議維持預設虛擬機器的Ergonomics機制自動開啟),在執行程式碼時,動態植入壓縮指令以節省記憶體消耗,但是開啟壓縮指標會增加執行程式碼數量,因為所有的Java堆裡的,指向Java堆內物件的指標都會被壓縮,這些指標的訪問就需要更多的程式碼才可以實現,而且並不只是讀寫欄位才受影響,在例項方法呼叫,子型別檢查等操作中也受影響,因為物件例項指向物件型別的引用也被壓縮了。

【lz筆記分分享之走近Java】第一部分的第一章節走近Java主要是瞭解了一下Java的基本知識,只知道這些理論知識我們就知道Java是可以幹什麼事的東東了。Java可以做什麼呢,Java可以用來程式設計,程式設計能做出些什麼來呢?比如:銀行系統,萬能的某寶,手機遊戲,嫦娥飛月系統等等,這麼強大的程式語言總得有個東西來支援執行吧?好吧,支援Java語言執行的就是虛擬機器了。
         對於lz來說Java語言的存在是神聖的(lz不排斥其它語言哈,只是幹一行,愛一行)。Java它體系完善,可以一次編譯到處執行。最最主要的是開源。有什麼能比開源讓lz更happy的呢。


僅以此筆記記錄程式設計的日子