a平台自身就提供这些功能?
3、JPMS如何解决现有问题?
JPMS具有两个重要的目标:
-
强封装(Strong encapsulation): 每一个模块都可以声明了哪些包是对外暴露的,java编译和运行时就可以实施这些规则来确保外部模块无法使用内部类型。
-
可靠配置(Reliable configuration):每一模块都声明了哪些是它所需的,那么在运行时就可以检查它所需的所有模块在应用启动运行前是否都有。
Java平台本身就是必须要进行模块化改造的复杂项目,通过Jigsaw项目落地。
3.1 Project Jigsaw
Modular development starts with a modular platform. —Alan Bateman 2016.9
模块化开始于模块化平台 。Project Jigsaw 有如下几个目标:
-
可伸缩平台(Scalable platform):逐渐从一个庞大的运行时平台到有有能力缩小到更小的计算机设备。
-
安全性和可维护性(Security and maintainability):更好的组织了平台代码使得更好维护。隐藏内部API和更明确的接口定义提升了平台的安全性。
-
提升应用程序性能(Improved application performance):只有必须的运行时runtimes的更小的平台可以带来更快的性能。
-
更简单的开发体验Easier developer experience:模块系统与模块平台的结合使得开发者更容易构建应用和库。
对Java平台进行模块化改造是一个巨大工程,JDK9之前,rt.jar是个巨大的Java运行时类库,大概有60MB左右。JDK9将其拆分成90个模块左右 ,如下图所示(图片来源《Java 9模块化开发》):
4 创建第一个Java模块
创建一个Java模块其实非常的简单。在目前Maven结构的项目下,只需要在java目录下,新建一个module-info.java文件即可。此时,当前目录就变成了一个Java模块及Maven模块。
--moudule1
---src
----main
-----java
------com.company.package1
------moudule-info.java
---pom.xml
5 模块化对现有应用的影响
5.1 你可以不用但是不能不懂
Java模块化目前并没有展现出其宣传上的影响,同时也鲜有类库正在做模块化的改造。甚至,本人在创建第一个模块的时候,就遇到了Lombook失效、深度反射失败、Spring启动失败以及无法动态部署的影响。因此,尽量不要尝试在线上环境使用模块化技术!不用,但是不代表你可以不懂!随着Java平台模块化的完成,运行在JDK9环境的Java程序就已经面临着Jar包和模块的协作问题。未雨绸缪,在发现问题的时候,模块化技术可以帮你快速的定位问题并解决问题。
例如,在从JDK8升级到JDK11时,我们经常会收到一下警告:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.jd.jsf.java.util.GregorianCalendar_$$_Template_1798100948_0 (file:/home/export/App/deliveryorder.jd.com/WEB-INF/lib/jsf-1.7.2.jar) to field java.util.Calendar.fields
WARNING: Please consider reporting this to the maintainers of com.jd.jsf.java.util.GregorianCalendar_$$_Template_1798100948_0
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
通过反射访问JDK模块内类的私有方法或属性,且当前模块并未开放指定类用于反射访问,就会出现以上告警。解决方式也必须使用模块化相关知识,可以使用遵循模块化之间的访问规则,也可以通过设置 –add-opens java.base/java.lang = ALL-UNNNAMED 破坏模块的封装性方式临时解决;
5.2 Java模块、Maven模块和OSGI模块的之间的关系。
Java模块化技术,理论上可以从Java底层解决模块和模块之间的模块依赖、多版本、动态部署等问题。 前文所述,在2017JDK9发布前夕,以IBM和Redhat为首的13家企业在JCP委员会上一手否决了Jigsaw项目作为Java模块化规范进入JDK9发布范围的规划。经过众多权衡,Java模块化规范中还是给Maven、Gradle和OSGI等项目保留了一席之地。目前,可以通过Java模块+Maven模块或者Java模块+OSGI模块的方式构建项目,可惜的是,使用多个技术相互合作,还是增加了复杂性。
5.3 模块化对类加载机制的影响
JDK9之后,首先取消了之前的扩展类加载器,这是清理之中,因为本身JRE扩展目录都已经不存在,取而代之的是平台类加载器。然后,类加载器的双亲委派模型机制进行了破坏,在子类将类委派给父类加载之前,会优先将当前类交给当前模块(Moudle)或层(Layer)的类加载器加载。所以会形成如下的类加载模型:
同时,在JDK9之后,引入的层(Layer)的概念,在Java程序启动时,会解析当前模块路径中的依赖关系,并形成一个依赖关系图包含在引导层(Bootstrap Layer)中,这个依赖关系图从此开始不再改变。因此,现在动态的新增模块要创建新的层,不同的层之间可以包含相同的模块。会形成如下所示的依赖关系(图片来源《Java 9模块化开发》):
综上所述,模块化改造对于使用自定义类加载器进行功能动态变化的程序还是巨大的,一旦使用模块化,必然会导致这类功能受到巨大影响。当然模块化技术普及还需要很长一段时间,会晚但是不会不来,提前掌握相关技术还是很必要。
5.4 总结
下面是Java模块化相关技术的一些核心脑图,可以学习参考:
二、垃圾回收器的一系列优化措施
2.1、ZGC-新一代垃圾回收器
JDK11中,最耀眼的新特性就是ZGC垃圾回收器。作为实验性功能,ZGC的特点包括:
-
GC停顿时间不会超过10ms。
-
停顿时间不会随着堆的大小,或者活跃对象的大小而增加;
-
相对于G1垃圾回收器而言,吞吐量降低不超过15%;
-
支持Linux/x64、window和mac平台;
-
支持8MB~16TB级别的堆回收。
同时根据openJDK官方的性能测试数据显示(JEP333),ZGC的表现非常的出色: