如果你是剛要被Java軍訓的新兵,可有幾時對環境搭建而不知所措?又如若你是馳騁Java戰場多年的老將,可曾拿起陪伴你許久的82年的JDK回味一番?今天我們就來道一道JDK,重新來認識認識這個既熟悉又陌生的伙伴,
既然要嘮嘮JDK,首先想到的,肯定是要了解下都是誰來推進Java和JDK發展的,
Java發展的會議與組織
說起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委員會還是主要由廠商組成,這些規范可能更偏向于廠商的利益,而非大眾的利益,
JDK版本
我們要知道Java應用開發并不是只有常接觸的移動端 、服務端的應用開發,Sun公司根據不同業務領域方向分成了四個JDK版本:
- Java Card,主要是以具有安全防護性的方式來執行小型的Java Applet,廣泛運用在SIM卡、提款卡上;
- Java SE,前稱J2SE,Java的標準版,為JavaEE和JavaME提供了基礎類別庫以及能力,也是我們安裝部署Java環境最基礎的版本;
- Java EE,前稱J2EE,針對企業級應用的加強版,主要涉及的技術:JDBC、EJB(被Spring遮住了光芒)、Servlet、RMI、JNDI、JMS、JPA、JTS等,Java 10版本以后被Oracle公司放棄,捐獻給了Eclipse基金會,并后成為Jakarta EE;
- Java ME,前稱J2ME,主要用于移動設備、嵌入式設備上的java應用程式;
Oracle JDK vs Open JDK
Open JDK現已作為Java版本迭代的發展標準,并且開源,而Oracle JDK只不過是Open JDK的具體實作,不完全對外開源,
至于它倆的區別,下面的串列基本列出:
| Oracle JDK | Open JDK | |
| 起源時間 | JDK1.0,1996年1月發行 | OpenJDK 6(基于Java SE 7),2007年發行 |
| 代碼協議 |
新的OTN協議,2019年1月之后發布的Oracle JDK 8更新將無法用于商業 |
GPLv2+CE |
| 發行周期 |
JDK6及之前大約每兩年一版本,6至7五年,7至8、8至9三年;JDK10及以后均6個月一個大版本;每3年一個LTS版本; |
OpenJDK 9及之前大約三年一個版本;OpenJDK 10及以后均6個月一個大版本; |
| 支持時間 |
從JDK10起,每6個月一個大版本;從JDK11起,每3年一個LTS長期維護的版本; |
從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的功能,還有ZGC; OpenJDK也會附帶JMC開源,當前還在開發中 |
如果你們公司既想應用新特性,又沒有授權的話,那就使用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 6、JavaEE 6、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包
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分成了三種實作,compact1、compact2和compact3,具體的拆分情況如下,可見數字越大,包含的內容越多,在編譯時,使用option: -profile,指定對應的實作方式即可,

JDK檔案組成
以windows環境的Java 8u261版本為例,針對JDK的組成架構進行解讀,先來了解下解壓或者安裝完JDK的檔案夾結構吧:

- bin目錄中存放了開發程序的編譯解釋工具,如java.exe、javac.exe等,以及開發運維作業中常用的資源消耗統計等不同功能的輔助工具,如jmap.exe、jconsole.exe、jstat.exe等,
- include目錄下可以看到都是以.h結尾的檔案,用來支持Java中用到的本地方法以及JVM除錯程式介面用到的本地技術,
- jre目錄則是jdk運行的開發環境時使用的runtime,如jdk bin目錄下的執行檔案都是建立在這個jre檔案夾的基礎上 !當然也是可以單純用于Java撰寫的程式,需要說明的,如果存在期望依賴的jar包(如中間件的驅動程式),可以放置于jre的lib目錄下的ext檔案夾 ,
- lib目錄是存放JDK bin目錄下可執行檔案依賴的jar包等,如常見的tools.jar;
- src.zip則是Java類別庫原始碼,主要包含rt.jar,以及程式啟動器Launcher原始碼,主要功能是創建ExtClassLoader和AppClassLoader,根據配置創建SercurityManager,設定行程背景關系類加載器;
JVM
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 依賴包
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壓縮包檔案操作 |
rt.jar介紹
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提供的工具
所有提供的工具按照類別分組情況如下,具體的使用方法可以下載JDK的檔案查看,
- 基本工具 (appletviewer, extcheck, jar, java, javac, javadoc, javah, javap, jdb, jdeps,jaotc)
- 安全工具 (keytool, jarsigner, policytool, kinit, klist, ktab)
- 國際化工具 (native2ascii)
- RMI工具 (rmic, rmiregistry, rmid, serialver)
- Java IDL和RMI-IIOP工具 (tnameserv, idlj, orbd, servertool)
- 部署工具 (javapackager, pack200, unpack200)
- Java Web Start工具 (javaws)
- 故障排除,性能分析,監視和管理工具 (jcmd, jconsole, jmc, jvisualvm)
- Web服務工具 (schemagen, wsgen, wsimport, xjc)
Java 9及以后
上述的組成架構圖,是基于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 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/116783.html
標籤:Java
上一篇:java中的方法
下一篇:static關鍵字設計原理
