回首Java——再回首JDK


如果你是剛要被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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM