Java8 迁移到 Java11 的过程

本贴最后更新于 1921 天前,其中的信息可能已经沧海桑田

🌹🌹 如果您觉得我的文章对您有帮助的话,记得在 GitHub 上 star 一波哈 🌹🌹

🌹🌹GitHub_awesome-it-blog 🌹🌹


0 背景

酷划商业平台容器化之后,应用的启动性能下降明显。经常出现 10 秒以上的接口响应延迟。分析了应用启动时的性能指标,发现 CPU 负载和使用率同时飙升(甚至打满),后来发现是 C2 编译器占用大量 CPU 时间片。遂决定优化之。

已经做的优化:

  • 调整多个 pod 的启动顺序:并行 -> 串行
  • 调整 JIT 编译线程数

初步优化后,将延迟降低到了 5 秒左右。

然后考虑,能不能将每次 JIT 编译的结果缓存下来,下次应用启动的时候直接使用,减少应用启动初期解释执行和收集 profile 带来的性能影响。

调研发现,目前已有的实现方案有以下几种:

  • Oracle Java9 以后的 AOT(配合 Graal 编译器使用)
  • 阿里 JDK-Dragonwell8(基于 JDK8,利用其 JWarmup 缓存 JIT 编译结果)
  • Azul Zing VM 的 ReadyNow
  • IBM J9 的 AOT

最终决定对前两种进行试验。

PS:本文只讨论 OracleJDK 的升级过程

1 升级 Java11 的目的

  • 利用 AOT 解决应用冷启动的性能问题
  • 新特性 http2 的使用
  • 容器相关的新特性的使用

2 初期遇到的问题

直接安装 Oracle JDK11,将 IDE 的环境切换到 JDK11 后,就开始各种报错。例如:

迁移初期问题 1.png

注解 PostConstruct 找不到了。这个问题是 Java11 中移除了 javax 包引起的。

然后开始翻官方文档,有一篇专门针对从 JDK8 升级到后面新版本的。

传送门:Migrating From JDK 8 to Later JDK Releases

这里面,主要关注哪些会导致应用编译失败或无法启动的更改。

主要有以下这些 API 移除:

  • 移除 java.* APIs 和 javax.* APIs
  • 移除 com.sun.*
  • 移除某些 jdk.*
  • java.awt.peer Not Accessible
  • Removed com.sun.image.codec.jpeg Package

另外下面的 GC 参数组合已失效,如果配置会导致启动报错:

  • DefNew + CMS
  • ParNew + SerialOld
  • Incremental CMS

由于移除了永久代,以下相关配置会导致一些警告:

  • -XX:MaxPermSize=size
  • -XX:PermSize=size

告警信息如下:

Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0

更详细的信息请参考官方文档的内容。

2.1 解决上面遇到的问题

上文中,切换到 JDK11 后,javax.annotation.PostConstruct 被移除了。我们可以手动将 javax.annotation 的 jar 包引入,即可解决。

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

其他的问题按照同样的思路解决即可。

3 远程 debug 问题

Java9 以后的版本,JPDA 的 address 配置格式发生了一些变化。

Java8 及以前,用如下形式:

-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

Java9 及以后,改为下面这样,否则无法链接到远程端口:

# 区别在于address,要变成 *:PORT 格式
-Xdebug -Xrunjdwp:transport=dt_socket,address=*:8000,server=y,suspend=n

原因:

可参考 StackOverflow 的一个 issue:What are Java command line options to set to allow JVM to be remotely debugged?

大概是说,Java9 及以后的版本默认只支持本地连接到 debug,即 address=8000,这个格式默认解析出来的 IP 是 localhost,改成 address=*:8000 后,可匹配任何 IP。

JDWP.png

延伸:

Java5 之前,使用-Xdebug 和-Xrunjdwp 来告知 jvm 运行在 debug 模式下,这个方式在以后的版本中仍然适用,但在此模式下运行的 JVM,只会在解释执行的模式下运行,不会有 JIT 的参与,所以运行较慢,因此生产环境一定不要开启这个参数。

后续...

采坑仍在继续,会在 GitHub 上持续更新。

GitHub_Mr 羽墨青衫

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3186 引用 • 8212 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone756 1 评论

    兄弟,是不是应该把 hacpai.com 加一下白名单?

    应该是因为 HTTPS 的问题
    88250
  • someone
    作者

    hacpai.com 的外链都挂了么?😰

    1 回复
  • 88250

    目前看来是的,主要是因为原图没有支持 HTTPS 哦 😂

  • someone 2
    作者

    刚开始玩 solo,抽空调整一下 🤝