若是你是剛要被Java軍訓的新兵,可有幾時對環境搭建而不知所措?又如若你是馳騁Java戰場多年的老將,可曾拿起陪伴你許久的82年的JDK回味一番?今天咱們就來道一道JDK,從新來認識認識這個既熟悉又陌生的夥伴。css
既然要嘮嘮JDK,首先想到的,確定是要了解下都是誰來推動Java和JDK發展的。html
提及Java的起源一定要提起Sun公司,由其發起了專屬於Java的JavaOne會議。不過Sun公司被Oracle收購後,JavaOne會議同Oracle先前的Oracle OpenWorld會議併成了Oracle Code One會議,而且會議內容也再也不單純討論Java的發展。另外還有JCP(Java Community Process)是個開放性的國際技術標準組織,職責是發展和更新Java 技術規範,由其推出了大量Java相關技術規範JSR,具體可點此查看。JCP的運做方式是由我的或者廠商提出JSR規範提案,再有JCP委員會的成員投票表決是否採用。其弊端是JCP委員會仍是主要由廠商組成,這些規範可能更偏向於廠商的利益,而非大衆的利益。java
咱們要知道Java應用開發並非只有常接觸的移動端 、服務端的應用開發。Sun公司根據不一樣業務領域方向分紅了四個JDK版本:node
至於它倆的區別,下面的列表基本列出:mysql
Oracle JDK | Open JDK | |
起源時間 | JDK1.0,1996年1月發行 | OpenJDK 6(基於Java SE 7),2007年發行 |
代碼協議 | 新的OTN協議,2019年1月以後發佈的Oracle JDK 8更新將沒法用於商業linux |
GPLv2+CE |
發行週期 | JDK6及以前大約每兩年一版本,6至7五年,7至八、8至9三年;JDK10及之後均6個月一個大版本;每3年一個LTS版本;正則表達式 |
OpenJDK 9及以前大約三年一個版本;OpenJDK 10及之後均6個月一個大版本;sql |
支持時間 | 從JDK10起,每6個月一個大版本;從JDK11起,每3年一個LTS長期維護的版本;shell |
從JDK10起,每6個月一個大版本;不發行LTS版本,只維護半年,也就是下個版本發佈便再也不維護。可是有其餘頂級公司繼續維護,如Red Hat OpenJDK,Liberica OpenJDK數據庫 |
商標 | java商標擁有者 | 不可以使用java |
性能 | 響應能力、JVM性能更強 | —— |
功能 | Flight Recorder,Java Mission Control和Application Class-Data Sharing |
Font Renderer,但OpenJDK 11後也包含Oracle JDK的功能,還有Z Garbage Collector |
若是大家公司既想應用新特性,又沒有受權的話,那就使用OpenJDK 11吧!畢竟Oracle的產品總監也說了,Oracle JDK是基於OpenJDK源代碼構建的,OracleJDK和OpenJDK在Java 11後,功能基本保持一致。可見連接:Oracle JDK Releases for Java 11 and Later。
JDK 1.0在1996年1月23日發佈,Java語言有了第一個正式版本的運行環境;
JDK 1.2,Sun公司正式將Java拆分紅J2SE,J2EE和J2ME三大技術體系;
JDK 1.6,終結了J2EE、J2SE、J2ME的命名方式,啓用Java SE 六、JavaEE 六、Java ME 6的命名方式。與此同時,Sun公司宣佈將對Java技術開源;
JDK 7,Sun公司被Oracle公司收購,發佈時間延期;
JDK 8,Oracle啓用JEP(JDK Enhancement Proposal)定義管理新版JDK發佈的新特性,完成了JDK 7規劃了但沒有實現的功能,HotSpot移除掉永久代,吸取了JRockit的Java Mission Control監控工具等功能;8u201/202版本後,若是是用做商業用途,須要收費;
JDK 9,jigsaw模塊化、加強jshell、jlink、jhsdb等工具,並支持了91個JEP;此前均以特性驅動發行版本。9開始變成以時間驅動,發佈週期爲6個月一個大版本,3年一個 LTS版本;
JDK 10,主要是JDK內部重構,只支持了12個JEP;Oracle公司拋棄Java EE,捐獻給Eclipse基金會;
JDK 11,推出了ZGC垃圾收集器(只支持64位的Linux機器),支持了17個JEP;第一個官宣的LTS發行版;
JDK 12:推出非Oracle開發的Shen-andoah垃圾收集器,OracleJDK隨後剔除了,存在於OpenJDK,支持了8個JEP;
JDK 13:支持5個JEP;
JDK 14:推出Windows和MacOS的ZGC垃圾收集器,支持16個JEP;
各版本具體的New Feature,你們能夠直接上Oracle官網追溯。或者查看我推薦的兩篇博文:博文1傳送門、博文2傳送門。我這裏就再也不贅述了,後面會開個專欄,去探索實踐Java每一個版本特性的實現。
JDK的運用,滲透到從事Java開發工做的各位的每一天,從開發到調試,再到發佈和部署,以及上線後的運維都息息相關。相信在座的各位,必定有過疑問,jdk究竟是怎麼組成的?瞭解這些可能對咱們的開發工做沒有太多的做用,可是哪位又能預料明天和bug哪一個先到呢,也許這就是你找到問題根因的地方!再不濟,學習點知識,總不會有壞處!跟隨個人腳步,一塊兒看看JDK究竟是怎麼構成的吧!
咱們先來看下官方文檔中Java SE版本JDK的組成架構圖:
很直接地能夠看出,最下面的Java HotSpot VM,是Java運行最基礎的組件;Java SE API即咱們平常編程使用的Java類庫;JRE是Java應用程序運行的最小環境,其中包括了JVM,Java SE API類庫和其餘標準或非標準組件;JDK包含了JRE和一些Tool。Java8增長新特性Compact Profiles,是由於Java豐富的類庫在小型應用中顯得有些累贅,便將JRE分紅了三種實現,compact一、compact2和compact3,具體的拆分狀況以下,可見數字越大,包含的內容越多。在編譯時,使用option: -profile,指定對應的實現方式便可。
以windows環境的Java 8u261版本爲例,針對JDK的組成架構進行解讀。先來了解下解壓或者安裝完JDK的文件夾結構吧:
Oracle官網po出組成架構圖最下面即是最基礎、最重要的JVM技術,是在真實計算機上模擬虛擬的計算機功能。正是它的存在,才成就了「一次編譯,屢次運行」;
Java8後提供了兩種模式的VM,一種是Client,一般用於客戶端應用程序,能夠減小應用的啓動時間和內存佔用,一種是Server,會提高運行時執行速度;在jvm.cfg文件中第一個是默認實現,默認是-server KNOWN,KNOWN可設置成IGNORE,這只是表示相應的option是否啓用。
此處列出兩個Q&A,這也是我最初接觸JVM的疑問。
Q1:JVM做爲Java程序最重要的組件,爲何文件夾裏沒有一個很明顯的文件表示用於JVM的呢?
A1:JVM以動態庫的形式存在,Windows上置於jre的bin文件夾下的server或者client文件夾裏的jvm.dll。Linux上置於jre的lib文件下的/amd**/server或者/amd**/client文件夾下的libjvm.so。
Q2:JVM是怎麼被加載並實例化的?
A2:JVM加載是經過java.exe來完成:首先經過launcher下的main函數建立JVM裝載環境、配置,而後裝載jvm.dll,裝載完成後經過JNI本地調用接口找到JNI_CreateJavaVM的函數地址,而後調用函數去實例化JNIEnv對象:JVM,最後便經過JVM實例裝載並處理class文件。代碼調用順序以下,童鞋可自行看下源碼:main() > JLI_Launch() > CreateExecutionEnvironment() > SetJvmEnvironment() > LoadJavaVM() > JVMInit() > JavaMain() > InitializeJVM() > CreateJavaVM() [調用JNI接口] > LoadMainClass() > GetApplicationClass() ;
哦~~原來是這樣啊!是否是對JVM進一步認識了呢?不過這纔是皮毛,剩下的等我開個專題慢慢道來!還不趕忙關注我?
JRE運行所依賴的jar包,包含在/jre/lib和/jre/lib/ext文件夾下,若是有jar包但願做爲JVM信任的Jar包第一時間加載,也能夠直接將jar包置於/jre/lib/ext文件夾下。介紹下全部依賴的jar包:
jar包 | 做用 |
access-bridge.jar | Microsoft Windows操做系統的Java Access Bridge使基於Windows的輔助技術能夠與Java Accessibility API進行交互; |
charsets.jar | 擴展的字符集。rt.jar中sun.nio.cs包下爲基礎的字符集; |
cldrdata.jar | 數據標準庫,用於數據的國際化和本地化。可見:cldr官網; |
deploy.jar | 用於部署應用的執行安裝程序; |
dnsns.jar | 處理DNS服務,暴露lookupAllHostAddr(),getHostByAddr()方法,用於InetAddress; |
jaccess.jar | Java Accessibility Utilities實用程序類的一部分,可幫助輔助技術提供對實現Java Accessibility API的GUI工具包的訪問; |
javaws.jar | JNLP協議,支持Java Web Start應用,能夠直接經過瀏覽器執行Java應用程序; |
jce.jar | 擴展的加密包; |
jfr.jar | Java飛行記錄器,是JMC的一個重要組成部分,用於記錄JVM和運行的Java程序的診斷數據、分析數據。對性能影響小於1%; |
jfxrt.jar | JavaFX的運行時核心jar包,至關於rt.jar |
jfxswt.jar | 爲JavaFX和Swing提供兼容性操做 |
jsse.jar | 用於驗證SSL鏈接的jar |
localedata.jar | 國際化的數據 |
management-agent.jar | 只有MANIFEST.MF一個文件,用於VisualVM或者JConsole等工具的代理jar包;可查看實際應用介紹 |
nashorn.jar | Java嵌入式的JS引擎,能夠實現js與Java的相互調用,還可使用jrunscript命令運行js; |
plugin.jar | 用於各類使用場景的插件jar包 |
resources.jar | 用於各類使用場景用到的靜態資源,如.properites,.png,.css,.txt等文件 |
rt.jar |
Java的runtime運行時核心代碼包 |
sunec.jar,sunjce_provider.jar, sunmscapi.jar,sunpkcs11.jar |
加密相關的jar包 |
zipfs.jar |
支持對zip壓縮包文件操做 |
Java SE版本涉及的基礎核心類庫,源碼則能夠將jdk的src.zip解壓後查看。可是並不是rt.jar中的全部包都是有源碼的。不知道具體緣由是什麼,有沒有了解的童鞋評論下點撥下。
具體API均可以在https://docs.oracle.com/javase/8/docs/api/index.html查看,或者下到電腦自行查看,不一樣版本的API直接將"/8/"變動成你須要的Java版本便可。
接下來介紹下組成架構圖中Java SE規範除去UI Toolkits的模塊以及功能。
模塊 | API規範 | 功能 |
lang and util | java.lang.* java.util.* |
提供幾乎全部Java應用程序的基本功能 |
Math | java.lang.Math java.lang.StrictMath java.math |
浮點數計算,數學公式計算 |
Management | java.lang.management java.util.logging.LoggingMXBean javax.management com.sun.management com.sun.tools.attach com.sun.tools.jconsole |
提供JVM、JConsole、JMX、日誌等監控管理功能 |
Versioning | java.lang.Class java.lang.ClassLoader java.lang.Package java.lang.System |
提供Class、Package管理功能 |
Ref Objects | java.lang.ref | 引用對象提供與GC有限交互功能 |
Reflection | java.lang.reflect | 反射提供從JVM中查看加載類、修改對象的功能 |
Collections | 基於java.util.Collection的實現 基於java.util.Map的實現 |
提供了功能強大、設計優秀的集合操做功能 |
Concurrency Utilities | java.utl.concurrent | 提供了強大且易擴展的高併發解決方法 |
JAR | java.util.jar java.net.JarURLConnection |
提供了Jar文件的處理功能 |
Logging | java.util.logging | 提供對日誌記錄的處理和交互 |
Preferences API | java.util.prefs | 提供對用戶和應用的首選項處理功能 |
Instrumentation | java.lang.instrument |
用於工具來檢測Java編程語言應用程序 |
Regular Expressions | java.util.regex |
正則表達式 |
ZIP | java.util.zip |
用於讀取和寫入標準ZIP和GZIP文件格式 |
Input/Output | java.io java.nio com.sun.nio |
提供針對文件和設備I/O處理的豐富功能 |
Serialization | java.io | 提供Java對象的序列化和反序列化功能 |
Networking | java.net javax.net com.sun.net jdk.net等 |
提供用於網絡處理的功能,包括尋址、鏈接、安全等 |
Security | java.security javax.crypto javax.rmi.ssl javax.xml.crypto javax.smartcardio com.sun.security org.ietf.jgss等 |
用於與安全相關的功能的API,如訪問控制,數字簽名,身份驗證和受權,加密等 |
Internationalization | java.util.spi java.util.Locale java.text.DecimalFormatSymbols等 |
支持開發國際化應用程序的API,能夠在不進行工程更改的狀況下適應各類語言和地區。 |
Beans | java.beans java.beans.beancontext |
主要提升了交互性和可維護性,JavaBeans的長期持久性能夠讀寫bean做爲其屬性值的文本表示形式 |
JMX | javax.management | Management Extension管理擴展,用於管理和監控資源使用 |
XML JAXP | javax.xml org.w3c.dom org.xml.sax |
用於處理XML文檔和數據 |
JNI | 用於編寫Java本機方法並將Java虛擬機嵌入本機應用程序的標準編程接口,能夠實現Java與其餘語言的交互。推薦一篇介紹如何使用JNI的文章 | |
Extension Mechanism | 支持擴展,jar包置於/jdk/jre/lib/ext,二進制文件置於/jdk/jre/bin,JVM會做爲可信任文件加載,不作安全檢查。已棄用,將來版本刪除此功能 | |
Override Mechanism | 除JCP外定義的Java API,能夠覆蓋成新版本做爲承認標準版本。將來版本刪除功能 | |
IDL | org.omg.CORBA org.omg.CosNaming org.omg.PortableServer org.omg.PortableInterceptor org.omg.DynamicAny |
使分佈式、支持Web的Java應用能夠基於IIOP協議透明地調用遠程服務 |
JDBC | java.sql javax.sql |
通用數據訪問接口,須要驅動進行鏈接。如經常使用的mysql-connector-java.jar |
JNDI | javax.naming |
提供命名和目錄功能,以通用方式訪問各類服務。如Spring定義的jndi-lookup能夠用於Wildfly部署的應用程序來創建數據庫鏈接 |
RMI | java.rmi |
提供調用遠程JVM中的Java對象的方法,使用對象序列化來封裝和解析 |
RMI-IIOP | org.omg.CORBA org.omg.CosNaming org.omg.PortableServer javax.rmi |
經過Internet Inter-ORB協議技術進行Java遠程方法調用RMI編程模型可經過RMI API進行CORBA服務器和應用程序的編程。 |
Scripting | javax.script |
腳本引擎接口,能夠實現動態腳本與java的交互,Java SE套件中含有nashorn引擎,可見nashorn.jar |
全部提供的工具按照類別分組狀況以下,具體的使用方法能夠下載JDK的文檔查看。
上述的組成架構圖,是基於Java 8的解析。在Java9前,因爲以前JRE必需要總體部署運行,會形成必定程度不指望的性能影響或者資源消耗。Oracle公司針對這方面的考慮,在JCP組織上作了不少的工做,終於在Java 9上實現了模塊化。
Java 9以前是經過不一樣的package和jar對功能作區分隔離,Java9後,能夠經過不一樣的module進行隔離。
若是打開JDK 9後文件夾,你會發現jre文件夾不存在了,出現了新的文件夾:jmods。文件夾下面的每一個文件都是一個組件,每一個組件都會有一個module-info.class文件。打開文件你會發現,存在着相似nodejs等語言經常使用的關鍵字:用requires引入須要的組件、 用exports暴露的包名;其中java.base是最基礎的模塊,其餘組件不須要顯示requires。
module java.sql {
requires transitive java.logging;
requires transitive java.transaction.xa;
requires transitive java.xml;
exports java.sql;
exports javax.sql;
uses java.sql.Driver;
}
筆者也還不曾使用過Java 8之後的版本編寫過項目,童鞋們有沒有優秀的文章分享分享呢?
經過上述的篇幅,咱們能夠知道:
1. JVM在JRE(JDK)中是以動態連接庫的形式存在的,windows中是jvm.dll,linux中是libjvm.so
2. JDK 8有3種實現的compact JRE,數字越大,功能越豐富
3. 組成架構圖中的Java SE API部分,位於/jre/lib和/jre/lib/ext文件夾下jar包中
4. rt.jar包是Java SE最爲核心的包
5. 組成架構圖中的Tools部分,位於jdk的bin目錄下的可執行的二進制文件
6. JDK 9後 Java SE API再也不是以jar形式存在,而是.jmod文件,針對不一樣的功能進行模塊化
如今對JDK的組成結構到實際開發運用是否有了進一步理解呢?有疑問的地方,歡迎童鞋們留言討論!
參考文章: 1. https://blog.csdn.net/topdeveloperr/article/details/89789132#jdk%E5%8C%85%E6%80%BB%E8%A7%88 2. https://segmentfault.com/a/1190000022711960 |