概念篇
1、從JDK8->JDK17 你需要知道的
從 JDK 8 升級到 JDK 17 可以讓你的應用程式受益于新的功能、性能改進和安全增強,下面是一些 JDK 8 升級到 JDK 17 的最佳實戰:
1.1、確定升級的必要性:首先,你需要評估你的應用程式是否需要升級到 JDK 17,查看 JDK 17 的新特性、改進和修復的 bug,以確定它們對你的應用程式是否有實際的好處,
1.2、了解 JDK 8 到 JDK 17 的變化:詳細了解 JDK 8 和 JDK 17 之間的差異是非常重要的,熟悉 JDK 17 中引入的新特性、移除的特性以及可能影響現有代碼的變化,
1.3、解決向后不兼容的變化 更新依賴項和框架:在升級程序中,可能會遇到一些向后不兼容和框架不兼容的變化,例如,一些 API 的使用方式可能發生了變化,或者一些方法已被廢棄,在升級之前,你需要對這些變化進行仔細的檢查,并相應地修改你的代碼,
1.4、進行兼容性測驗:在升級之前,進行兼容性測驗是非常重要的,確保你的應用程式在 JDK 17 下能夠正常運行,并且沒有出現任何性能下降或功能問題,可以使用自動化測驗工具來簡化測驗程序,
1.5、逐步升級:對于大型應用程式或關鍵系統,建議逐步進行升級,可以先將應用程式遷移到較新的 JDK 版本,如 JDK 11 或 JDK 14,然后再逐步升級到 JDK 17,這樣可以降低升級程序中的風險,并使你能夠逐步解決遇到的問題,
1.6、監控和優化性能:升級到 JDK 17 后,你可能會注意到一些性能改進,然而,某些代碼可能會受到影響并表現出不同的行為,使用性能監控工具來檢測潛在的性能問題,并進行必要的調整和優化,
1.7、 更新部署和運維流程:升級 JDK 版本后,你可能還需要更新你的部署和運維流程,例如,JDK 17 中引入了一些新的命令列工具和管理選項
2、為什么要使用jdk17?
2.1、長期支持(LTS):JDK 版本中的一些版本被標記為長期支持版本,這意味著它們將獲得更長時間的支持和維護,JDK 17 是 OpenJDK 的一個 LTS 版本
2.2、生態系統支持:一些開源專案、框架和工具可能會更早地支持較新的 JDK 版本,以利用新的特性和改進,選擇較新的 JDK 版本可以使你能夠使用最新的工具和庫,并獲得更好的生態系統支持
2.3、新功能和改進:每個 JDK 版本都會引入新的功能、增強和改進
3、強強聯合GraalVM
GraalVM 是一種開源的 通用 虛擬機(通用: 它具有支持多種編程語言的能力 直接在 graalvm 運行 不需要額外的運行時環境),具有許多特性和優勢,使得它在特定的場景中成為一個有吸引力的選擇,以下是一些使用 GraalVM 的原因:
3.1、高性能:GraalVM 具有優化的即時編譯器,能夠將 Java 程式編譯成高效的機器碼,在許多情況下比傳統的 Java 虛擬機更快,
3.2、AOT 編譯:GraalVM 可以將 Java 程式靜態編譯成本地機器碼,這被稱為 Ahead-of-Time(AOT)編譯,AOT 編譯可以提供更快的啟動時間和更低的記憶體消耗,適用于一些對性能要求較高的場景,
3.3、生態系統支持:GraalVM 在開發者社區中有廣泛的支持和活躍的生態系統,許多開源專案和框架已經對 GraalVM 進行了優化和集成,使得使用 GraalVM 更加方便和無縫
3.4、嵌入式支持:GraalVM 提供了嵌入式 API,允許你將 GraalVM 作為庫集成到你的應用程式中,這意味著你可以將 GraalVM 作為運行時引擎嵌入到你的應用程式中,從而實作更高的靈活性和自定義性,
3.5、云原生支持:GraalVM 具有與云原生應用程式開發和部署相關的特性,它可以與 Docker 和 Kubernetes 配合使用,支持快速啟動和低記憶體消耗,適用于云環境中的微服務架構,
實戰篇
1、第一步建議先升級依賴項
如果你的專案基于java 8,在升級前最好先升級依賴項,從java 8升級到java 17是一個很大的跨越,依賴項不升級則出問題的概率會比較高,maven可以用mvn versions:display-dependency-updates命令檢查依賴項更新,輸出會類似這樣
然后可以把依賴項升級到輸出的對應版本,大部分包升級不會出問題,如果有問題,建議去出問題的依賴官方倉庫尋找解決方案,這個命令是直接查詢maven遠程倉庫,如果依賴項多的話會運行比較長的時間
或者 jdeps --jdk-internals --multi-release 17 --class-path . encloud-api.jar
javax.annotation.*被移除 可以手動倒入
dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
常見的標記為廢棄的引數 遷移前后的引數如下:
2、環境安裝
2.1、Jdk環境安裝 https://www.graalvm.org/downloads/
版本對比
升級時springboot和springcloud版本對應表 https://start.spring.io/actuator/info
2.2、maven環境安裝
https://maven.apache.org/download.cgi
GraalVM對maven沒有特定的版本要求,通常情況下,只要您使用的Maven版本足夠新并支持Java 8或更高版本,就可以與GraalVM一起使用,建議您使用Maven 3.5.x 或更高版本以確保與GraalVM的兼容性
啟動java器使用 GraalVM 默認編譯器 Graal 運行 JVM,安裝時檢查Java版本:
$JAVA_HOME/bin/java -version
3、二進制的生成
3.1、安裝本機映像
gu install native-image
該native-image工具安裝在$JAVA_HOME/bin目錄中
3.2、maven構建
mvn clean package -Pnative -Dmaven.test.skip=true
4、出現的坑點
4.1、對于mac 提前安裝 glibc-devel
4.2、對于 centos 提前安裝
yum install centos-release-scl
yum install devtoolset-8
source /opt/rh/devtoolset-8/enable
yum install zlib-devel
否則編譯出現 會編譯失敗 gcc需要升級到6.4以上


4.3、對于java 應用來說 打出來的二進制可能出現亂碼 因此需要強制指定
5、模塊化 初體驗
git clone https://github.com/graalvm/graalvm-demos
cd graalvm-demos/native-hello-module
結構圖
├── hello
│ └── Main.java
│ > package hello;
│ >
│ > public class Main {
│ > public static void main(String[] args) {
│ > System.out.println("Hello from Java Module: "
│ > + Main.class.getModule().getName());
│ > }
│ > }
│
└── module-info.java
> module HelloModule {
> exports hello;
> }
mvn package
$JAVA_HOME/bin/java --module-path target/HelloModule-1.0-SNAPSHOT.jar --module HelloModule
$JAVA_HOME/bin/native-image --module-path target/HelloModule-1.0-SNAPSHOT.jar --module HelloModule
./hellomodule
6、編譯器操作模式
Graal 作為 HotSpot JIT 編譯器有兩種運行模式: libgraal:Graal 編譯器提前編譯到本地共享庫中,在這種運行模式下,共享庫由 HotSpot VM 加載,編譯器使用與 HotSpot 堆分開的記憶體,并且從一開始就運行得很快,因為它不需要預熱,這是默認和推薦的操作模式,
jargraal:Graal 編譯器經歷與 Java 應用程式的其余部分相同的預熱階段,也就是說,在編譯其熱方法之前首先對其進行解釋,-XX:-UseJVMCINativeLibrary使用命令列選項選擇此模式,這將延遲達到最佳性能的時間,
7、本機映像構建配置
maven常用配置
<buildArgs>
如果要將其他引數傳遞給本機影像生成器,請<buildArgs> 在插件的配置中使用
<buildArgs>
<arg>--argument</arg>
</buildArgs>
<skipNativeBuild>
要跳過本機影像的生成,請在插件的配置中提供以下內容:
<skipNativeBuild>true</skipNativeBuild>
<skipNativeTests>
要跳過本機影像編譯測驗的生成和執行,請在插件的配置中提供以下內容:
<skipNativeTests>true</skipNativeTests>
<debug>
如果要啟用除錯資訊的生成,請在插件配置中提供以下內容:
<debug>true</debug>
<useArgFile>
如果要使用引數檔案構建原生影像,請在插件配置中提供以下內容:
<useArgFile>true</useArgFile>
8、日志記錄添加到本機可執行檔案
1、默認情況下,由 Native Image 生成的本機可執行檔案支持通過java.util.logging.*API 進行日志記錄,
2、本機可執行檔案中的默認日志記錄配置基于logging.properties在 JDK 中找到的檔案,該檔案配置了一個java.util.logging.ConsoleHandler只顯示該INFO級別及以上級別的訊息的檔案,如果您需要額外的日志記錄處理程式,則必須注冊相應的類以進行反射,例如,如果您使用java.util.logging.FileHandlerthen 提供以下反射配置:
{
"name" : "java.util.logging.FileHandler",
"methods" : [
{ "name" : "<init>", "parameterTypes" : [] },
]
}
3、將以下 Java 代碼保存到名為LoggerRunTimeInit.java的檔案中,然后使用以下命令對其進行編譯javac:
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class LoggerTest {
public static void main(String[] args) throws IOException {
LogManager.getLogManager().readConfiguration(LoggerRunTimeInit.class.getResourceAsStream("/logging.properties"));
Logger logger = Logger.getLogger(LoggerRunTimeInit.class.getName());
logger.log(Level.WARNING");
}
}
4、下載logging.properties資源檔案 ( https://www.graalvm.org/docs/reference-manual/native-image/assets/logging.properties )并將其保存在與LoggerRunTimeInit.java相同的目錄中,
5、構建并運行本機可執行檔案
native-image LoggerTest -H:IncludeResources="logging.properties"
./LoggerTest
6、它應該產生類似于以下內容的輸出:
WARNING
9、使用jdk17和graalvm 你可以體驗到:
1.啟動時間:GraalVM 提供了 Just-In-Time (JIT) 編譯和 Ahead-Of-Time (AOT) 編譯的能力,AOT 編譯可以將 Java 應用程式編譯成本地機器碼,從而加快應用程式的啟動時間,相比之下,傳統的 JIT 編譯需要一些啟動時間來進行動態編譯,因此,使用 GraalVM 的 AOT 編譯可能會顯著減少啟動時間,提高應用程式的回應性能,
2.記憶體占用:GraalVM 的 AOT 編譯可以減少應用程式的記憶體占用,因為本地機器碼通常比解釋執行的位元組碼更加緊湊,這可以提高應用程式的可擴展性和資源利用率,
3.即時編譯性能:GraalVM 的 JIT 編譯器在某些情況下可能會提供更好的性能,它可以對熱點代碼進行更優化的編譯,以提高執行速度,這可能在一些計算密集型任務或高并發場景中帶來性能提升,
4.應用本身大小:在真實環境下占用對比 且二進制版本是已經整合5個專案的完整專案 而jar只是其中1/5
10、demo開箱即體驗
經過真實專案驗證的框架demo已上傳至github、地址:kafka-stream 基于JDK17+springboot3.0.6+kafkaStream構成 支持 native-image打包 讓您下的開心 用的舒心 歡迎大家體驗
作者:京東科技 徐擁
來源:京東云開發者社區
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/554319.html
標籤:Java
上一篇:演算法 in Go:Binary Search(二分查找)
下一篇:返回列表
