若是你是刚要被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 |