回首Java——再回首JDK

若是你是剛要被Java軍訓的新兵,可有幾時對環境搭建而不知所措?又如若你是馳騁Java戰場多年的老將,可曾拿起陪伴你許久的82年的JDK回味一番?今天咱們就來道一道JDK,從新來認識認識這個既熟悉又陌生的夥伴。css

既然要嘮嘮JDK,首先想到的,確定是要了解下都是誰來推動Java和JDK發展的。html

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委員會仍是主要由廠商組成,這些規範可能更偏向於廠商的利益,而非大衆的利益。java

JDK版本

咱們要知道Java應用開發並非只有常接觸的移動端 、服務端的應用開發。Sun公司根據不一樣業務領域方向分紅了四個JDK版本:node

  • 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

至於它倆的區別,下面的列表基本列出: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包

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,指定對應的實現方式便可。

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)
  • 安全工具 (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

相關文章
相關標籤/搜索