Java程式員為什麼要瞭解虛擬機相關的知識 Java程式在設計之初就號稱“一次編譯,到處運行”。Java之所以能做到“一次編譯,處處運行”是因為Java虛擬機隱藏了底層技術的複雜性以及機器和操作系統的差異性。 運行程式的物理機千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統一的運行平臺,實 ...
Java程式員為什麼要瞭解虛擬機相關的知識
Java程式在設計之初就號稱“一次編譯,到處運行”。Java之所以能做到“一次編譯,處處運行”是因為Java虛擬機隱藏了底層技術的複雜性以及機器和操作系統的差異性。
運行程式的物理機千差萬別,而Java虛擬機則在千差萬別的物理機上面建立了統一的運行平臺,實現了在任意一臺Java虛擬機上編譯的程式,都能在任何其他Java虛擬機上正常運行。
這一極大的優勢使得Java應用的開發比傳統C/C++應用的開發更高效快捷,程式員可以把主要精力放在具體業務邏輯,而不是放在保障物理硬體的相容性上。通常情況下,一個程式員只要瞭解了必要的Java類庫API、Java語法,學習適當的第三方開發框架,就已經基本滿足日常開發的需要了。
隨著Java技術的不斷發展,它已被應用於越來越多的領域之中。其中一些領域,如互聯網、能源、金融、通信等,對程式的性能、穩定性和擴展性方面會有極高的要求。
一段程式很可能在10個人同時使用時完全正常,但是在10000個人同時使用時就會緩慢、死鎖甚至崩潰。毫無疑問,要滿足10000個人同時使用,需要更高性能的物理硬體,但是在絕大多數情況下,提升硬體性能無法等比例提升程式的運行性能和併發能力,甚至有可能對程式運行狀況沒有任何改善。這裡面有Java虛擬機的原因:為了達到“所有硬體提供一致的虛擬平臺”的目的,犧牲了一些硬體相關的性能特性。如果開發人員不瞭解虛擬機諸多技術特性的運行原理,就無法寫出最適合虛擬機運行和自優化的代碼。
Java技術體系
如果僅從傳統意義上來看,JCP官方所定義的Java技術體系包括了以下幾個組成部分:
- Java程式設計語言
- 各種硬體平臺上的Java虛
- Class文件格式
- Java類庫API
- 來自商業機構和開源社區的第三方Java類庫
JCP:就是人們常說的“Java社區”,這是一個由業界多家技術巨頭組成的社區組織,用於定義和發展Java的技術規範。
Java發展歷
JDK 1.0發佈
1996年1月23日,JDK 1.0發佈,Java語言有了第一個正式版本的運行環境。JDK 1.0提供了一個純解釋執行的Java虛擬機實現(Sun Classic VM)。JDK 1.0版本的代表技術包括:Java虛擬機、Applet、AWT等。
JDK 1.1發佈
1997年2月19日,Sun公司發佈了JDK 1.1,Java里許多最基礎的技術支撐點(如JDBC等)都是在JDK 1.1版本中提出的,JDK 1.1版的技術代表有:JAR文件格式、JDBC、JavaBeans、RMI等。Java語言的語法也有了一定的增強,如內部類(Inner Class)和反射(Reflection)都是在這時候出現的。
JDK 1.2發佈
1998年12月4日,JDK迎來了一個裡程碑式的重要版本:工程代號為Playground(競技場)的JDK 1.2。
Sun在這個版本中把Java技術體系拆分為三個方向,分別是面向桌面應用開發的J2SE(Java 2 Platform,StandardEdition)、面向企業級開發的J2EE(Java 2 Platform,Enterprise Edition)和麵向手機等移動終端開發的J2ME(Java 2 Platform,Micro Edition)。
J2EE:J2EE包含13種核心技術,分別包括JDBC, JNDI, EJBs, RMI, JSP, Java servlets, XML, JMS, Java IDL, JTS, JTA, JavaMail 和 JAF。具體介紹可以參考這篇博客
J2EE在JDK 10以後被Oracle認為是一個不賺錢的業務,捐獻給Eclipse基金會管理,但是不允許使用Java商標,所以改稱為Jakarta EE。
在這個版本中出現的代表性技術非常多,如EJB、Java Plug-in、Java IDL、Swing等,並且這個版本中Java虛擬機第一次內置了JIT(Just In Time)即時編譯器(JDK 1.2中曾並存過三個虛擬機,Classic VM、HotSpot VM和Exact VM,其中Exact VM只在Solaris平臺出現過;後面兩款虛擬機都是內置了JIT即時編譯器的,而之前版本所帶的Classic VM只能以外掛的形式使用即時編譯器)。在語言和API層面上,Java添加了strictfp關鍵字,Java類庫添加了現在Java編碼之中極為常用的一系列Collections集合類等。
JDK 1.3發佈
2000年5月8日,工程代號為Kestrel(美洲紅隼)的JDK 1.3發佈。相對於JDK1.2,JDK 1.3的改進主要體現在Java類庫上(如數學運算和新的Timer API等),JNDI服務從JDK 1.3開始被作為一項平臺級服務提供(以前JNDI僅僅是一項擴展服務),使用CORBA IIOP來實現RMI的通信協議,等等。這個版本還對Java 2D做了很多改進,提供了大量新的Java 2D API,並且新添加了JavaSound類庫。
JDK 1.4發佈
2002年2月13日,JDK 1.4發佈,工程代號為Merlin(灰背隼)。JDK 1.4是標志著Java真正走向成熟的一個版本,Compaq、Fujitsu、SAS、Symbian、IBM等著名公司都有參與功能規劃,甚至實現自己獨立發行的JDK 1.4。哪怕是在近二十年後的今天,仍然有一些主流應用能直接運行在JDK 1.4之上,或者繼續發佈能運行在1.4上的版本。JDK 1.4同樣帶來了很多新的技術特性,如正則表達式、異常鏈、NIO、日誌類、XML解析器和XSLT轉換器,等等。
JDK 5發佈
2004年9月30日,JDK 5發佈,工程代號為Tiger(老虎)。Sun公司從這個版本開始放棄了謙遜的“JDK 1.x”的命名方式,將產品版本號修改成了“JDK x”。從JDK 1.2以來,Java在語法層面上的變動一直很小,而JDK 5在Java語法易用性上做出了非常大的改進。如:自動裝箱、泛型、動態註解、枚舉、可變長參數、遍歷迴圈(foreach迴圈)等語法特性都是在JDK 5中加入的。在虛擬機和API層面上,這個版本改進了Java的記憶體模型(Java Memory Model,JMM)、提供了java.util.concurrent併發包等。另外,JDK 5是官方聲明可以支持Windows 9x操作系統的最後一個JDK版本。
JDk 6發佈
2006年12月11日,JDK 6發佈,工程代號為Mustang(野馬)。
在這個版本中,Sun公司終結了從JDK 1.2開始已經有八年曆史的J2EE、J2SE、J2ME的產品線命名方式,啟用Java EE 6、Java SE 6、Java ME 6的新命名來代替。
JDK 6的改進包括:提供初步的動態語言支持(通過內置Mozilla JavaScript Rhino引擎實現)、提供編譯期註解處理器和微型HTTP伺服器API,等等。同時,這個版本對Java虛擬機內部做了大量改進,包括鎖與同步、垃圾收集、類載入等方面的實現都有相當多的改動。
JDK 6發佈後,Sun公司把Java開源了,形成了OpenJDK項目。OpenJDK和JDK的代碼基本一致,除了極少量的產權代碼(Encumbered Code,這部分代碼所有權不屬於Sun公司,Sun本身也無權進行開源處理)外,OpenJDK幾乎擁有了當時JDK的全部代碼。
我們可以這樣簡單理解兩者的關係。JDK的的代碼是master主分支上的代碼,openJDK是從master上拉出來的一個產品線,在這個分支上刪除了Encumbered Code等這些產權代碼。所以如果你用不到這些產權特性的話,JDK和OpenJDK可以認為是一致的。
JDK 7發佈
在JDK 7發佈之前,Java的老東家Sun公司被Oracle收購了。在原本計劃在JDK 7中發佈的很多特性不能如期完成。
為了保證如期發佈JDK 7,Oracle大幅裁剪了JDK 7預定目標,以保證JDK 7的正式版能夠於2011年7月28日準時發佈。主要措施是把不能按時完成的Lambda項目、Jigsaw項目和Coin項目的部分改進延遲到JDK 8之中。
最終,JDK 7包含的改進有:提供新的G1收集器(G1在發佈時依然處於Experimental狀態,直至2012年4月的Update 4中才正式商用)、加強對非Java語言的調用支持(JSR-292,這項特性在到JDK 11還有改動)、可並行的類載入架構等。
JDK 8發佈
2014年3月18日,JDK 8發佈。從JDK 8開始,Oracle啟用JEP(JDK Enhancement Proposals)來定義和管理納入新版JDK發佈範圍的功能特性。JDK 8提供了那些曾在JDK 7中規划過,但最終未能在JDK 7中完成的功能,主要包括:
- JEP 126:對Lambda表達式的支持,這讓Java語言擁有了流暢的函數式表達能力。
- JEP 104:內置Nashorn JavaScript引擎的支持。
- JEP 150:新的時間、日期API。
- JEP 122:徹底移除HotSpot的永久代。
以上只是列出了JDK 8的部分新特性。
JDK 9發佈
2017年9月21日,JDK 9發佈。JDK 9主要發佈了Jigsaw(支持Java模塊化,對標OSGi),除了Jigsaw外,JDK 9還增強了若幹工具(JS Shell、JLink、JHSDB等),整頓了HotSpot各個模塊各自為戰的日誌系統,支持HTTP 2客戶單API等91個JEP。
JDK 9以後,Oracle宣佈每六個JDK大版本中才會被划出一個長期支持(Long Term Support,LTS)版,只有LTS版的JDK能夠獲得為期三年的支持和更新,普通版的JDK就只有短短六個月的生命周期。JDK 8和JDK 11會是LTS版,再下一個就到2021年發佈的JDK 17了。
JDK 10發佈
2018年3月20日,JDK 10如期發佈,這版本的主要研發目標是內部重構,諸如統一源倉庫、統一垃圾收集器介面、統一即時編譯器介面(JVMCI在JDK 9已經有了,這裡是引入新的Graal即時編譯器)等,這些都將會是對未來Java發展大有裨益的改進,但對普通用戶來說JDK 10的新特性就顯得乏善可陳,畢竟它只包含了12個JEP,而且其中只有本地類型推斷這一個編碼端可見的改進。
JDK10以後,Oracle選擇把J2EE“掃地出門”,所有權直接贈送給Eclipse基金會,唯一的條件是以後不准再使用“Java”這個商標[插圖],所以取而代之的將是Jakarta EE。
JDK 11發佈
2018年9月25日,JDK 11發佈,這是一個LTS版本的JDK,包含17個JEP,其中有ZGC這樣的革命性的垃圾收集器出現,也有把JDK 10中的類型推斷加入Lambda語法這種可見的改進。
JDK 12發佈
2019年3月20日,JDK 12發佈,只包含8個JEP,其中主要有Switch表達式、Java微測試套件(JMH)等新功能,最引人註目的特性無疑是加入了由RedHat領導開發的Shen-andoah垃圾收集器。
Shenandoah作為首個由非Oracle開發的垃圾收集器,其目標又與Oracle在JDK 11中發佈的ZGC幾乎完全一致,兩者天生就存在競爭。Oracle馬上用實際行動抵制了這個新收集器,在JDK 11發佈時才說應儘可能保證OracleJDK和OpenJDK的相容一致,轉眼就在OracleJDK 12里把Shenandoah的代碼通過條件編譯強行剔除掉,使其成為歷史上唯一進入了OpenJDK發佈清單,但在OracleJDK中無法使用的功能。
參考
- 《深入理解Java虛擬機》
公眾號推薦
歡迎大家關註我的微信公眾號「程式員自由之路」