<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring 官宣:換掉 JVM!

          共 405字,需瀏覽 1分鐘

           ·

          2022-05-28 03:22



          Spring 團隊日前發(fā)布了 Spring Native Beta 版。通過 Spring Native,Spring 應(yīng)用將有機會與?GraalVM?原生鏡像的方式運行為了更好地支持原生運行,Spring Native 提供了 Maven 和 Gradle 插件,并且提供了優(yōu)化原生配置的注解。
          Spring 發(fā)布了 Spring Native 的 beta 版本,并在http://start.spring.io上運行它
          實際上,這意味著自Spring成立以來,除了Spring支持的常規(guī)Java虛擬機之外,我們還將添加Beta支持,以使用GraalVM將Spring應(yīng)用程序編譯到本機映像中,從而提供一種部署Spring應(yīng)用程序的新方法。支持Java和Kotlin。
          這些本機Spring應(yīng)用程序可以部署為獨立的可執(zhí)行文件(無需安裝JVM,并提供有趣的特性,包括幾乎即時啟動(通常<100ms),即時峰值性能和較低的內(nèi)存消耗,但所需的構(gòu)建時間和運行時優(yōu)化次數(shù)少于JVM。

          使用簡單mvn spring-boot:build-imagegradle bootBuildImage命令,您可以生成一個優(yōu)化的容器映像,該映像將包含一個最小的OS層和一個小的本機可執(zhí)行文件,該映像僅隨附JDK,Spring以及您在應(yīng)用程序中使用的依賴項中的必需位。

          請參閱下面的示例,其中包含50MB可執(zhí)行文件的最小容器映像,其中包含Spring Boot,Spring MVC,Jackson,Tomcat,JDK和應(yīng)用程序。

          這種原生方式,在很多場景下都會對 Spring 應(yīng)用產(chǎn)生價值:

          在使用場景上,比如 Piotr Mińkowski 提供了一個非常棒的指南,介紹了如何在 Knative 上使用 Spring Boot 和 GraalVM 構(gòu)建原生微服務(wù)。

          其實這個技術(shù)在阿里,他們也探索了兩種不同維度上的冷啟動加速技術(shù),經(jīng)過雙 11 大促的檢驗都取得了良好的效果:AppCDS 技術(shù)在傳統(tǒng) Java 環(huán)境的維度上,利用類數(shù)據(jù)共享特性改進啟動速度和減少內(nèi)存開銷;靜態(tài)編譯技術(shù)則在更為激進的維度上,將 Java 程序提前編譯為二進制機器碼,實現(xiàn)以 Native Code 的速度啟動 Java 程序,帶來最多兩個數(shù)量級的啟動性能提升。


          阿里JVM 團隊技術(shù)專家林子熠博士在最新出版的《GraalVM與Java靜態(tài)編譯:原理與應(yīng)用》一書中,揭秘Oracle GraalVM中Java靜態(tài)編譯技術(shù)的特性、實現(xiàn)原理、應(yīng)用與調(diào)試技巧,以突破Java“冷啟動”桎梏,實現(xiàn)啟動性能“質(zhì)”的飛躍。

          作者介紹?:林子熠 博士




          以下是來自林老師QCon北京大會的分享,以期幫你實現(xiàn)云原生場景下 Java 快速冷啟動(下文以林子熠老師第一人稱敘述)

          Java 誕生至今的 25 年里,憑借其峰值性能高、語言功能強、生態(tài)支持好等特點贏得了語言市場的霸主地位。但 Java 冷啟動開銷大,而云原生時代下的應(yīng)用程序短小,啟動頻繁,冷啟動問題的解決機不容發(fā)。

          冷啟動問題根因及應(yīng)對

          下圖為典型 Java 應(yīng)用的生命周期:

          如圖,Java 應(yīng)用生命周期分為 5 個階段:VM 初始化階段、APP 初始化階段、APP 初活躍階段、APP 穩(wěn)定執(zhí)行期、結(jié)束階段。

          VM 初始化(圖中紅色)和 Class loading(圖中藍色)的開銷為冷啟動的根因。阿里巴巴實現(xiàn)了兩類改造:一類為改良型技術(shù),調(diào)整優(yōu)化現(xiàn)有 Java 的框架和運行模型,另外一類為革新型的技術(shù),擺脫原有 Java 框架另起爐灶。

          EagerAppCDS

          改良型技術(shù)中,阿里巴巴主要實現(xiàn)了基于傳統(tǒng) CDS(Class Data Sharing)的 EagerAppCDS。傳統(tǒng) CDS 包括 mark、Klass*、fields 三部分,如下圖所示:

          Klass* 指針指向內(nèi)存中 class 實例 InstanceKlass,該實例為 bytecode Class Loading 解析后生成的,但在多次解析時內(nèi)容均不變,因此可固定存儲磁盤文件 Shared Archive 中,下次運行時從文件中可省略解析直接讀取,實現(xiàn)提速。

          面對 system class,CDS 可根據(jù) name 快速匹配,但面對 customized class 時,JVM 無法辨認 customized class loader 的身份,因此需在 classpath 上掃描 jar 包,根據(jù) name、crc 校驗后方可完成匹配。jar 包即為 libs 包,包含大量 I/O 操作,開銷大。EagerAppCDS 用 identity 固定了 customized class loader 的名字,可直接通過 identity+name 匹配找到所需 class。

          下圖為 EagerAppCDS 在阿里巴巴內(nèi)部實踐的脫敏數(shù)據(jù),如圖所示性能提升效果從 12%~95% 不等。

          EagerAppCDS 雖未開源但已在阿里云 SAE(Serverless 微服務(wù) PaaS 平臺)上線。線上可公開實測數(shù)據(jù)中應(yīng)用啟動耗時降低 5%~45%,提升效果與啟動時加載類數(shù)量成正比。

          除此之外,我們還實現(xiàn)了以下改進型技術(shù):

          Graal VM 靜態(tài)編譯技術(shù)
          革新型技術(shù)中,阿里巴巴采用了基于 Graal VM 的靜態(tài)編譯技術(shù)。Graal VM 為 Oracle 主導(dǎo)的基于 Java 的開源高性能多語言平臺:C++、Kotlin、python 等多種語言可通過 Truffle 框架運行在 GraalVM 上,Java 和其他 JVM 語言(如 Groovy、Kotlin 和 Scala 等)編譯成 bytecode 后可直接運行。
          Substrate VM(SVM)為 Graal VM 的靜態(tài)編譯組件,可將 Java 程序靜態(tài)編譯為可執(zhí)行文件或共享庫文件 Native Image,實現(xiàn)直接編譯 Java 代碼。
          Java 最初依靠解釋器實現(xiàn)無需編譯實時執(zhí)行;該解釋器性能較差,因此引入了 JIT(Just In Time)實時編譯技術(shù),將高熱度函數(shù)送到編譯器中編譯;為解決編譯器開銷大的問題,引入了 AOT(Ahead Of Time)編譯,提前編譯部分代碼;AOT 缺乏 runtime 數(shù)據(jù),運行后即喪失轉(zhuǎn)為 JIT 的機會,運行速度慢;靜態(tài)編譯技術(shù)將 AOT 擴大,徹底摒棄 JVM,由 SVM 提供運行環(huán)境。

          靜態(tài)編譯基本原理

          傳統(tǒng) Java 執(zhí)行模型如下圖所示:Application(應(yīng)用本身)在 libs 的支持下運行在 JDK 上在 JVM 中執(zhí)行。

          靜態(tài)編譯在 Graal Compiler 編譯器中編譯 Application、libs、JDK,同時編譯 Substrate VM Runtime,獲得 Native Image。Native Image 包含 code(編譯后的代碼)和 Image heap(存儲數(shù)據(jù))兩部分。Image heap 為運行時 heap 的起點,直接讀取 Image heap 可以提高運行時的性能。

          靜態(tài)編譯必須遵循封閉性原則 (the closed-world assumption),即所有運行時信息均需在編譯時可見。該原則帶來兩個基本問題:如何確定封閉的邊界?如何處理 Java 的動態(tài)特性?

          靜態(tài)分析

          Java bytecode 編譯為 Native code 時,代碼抽象性降低體積增大,如若編譯所有代碼,Native Image 體積將過于龐大,因此需確定封閉邊界。SVM 通過靜態(tài)分析上實現(xiàn)了從給定入口開始確定程序可達范圍的功能。

          該技術(shù)應(yīng)用廣泛,例如 main 函數(shù)調(diào)用 Virtue call 必須先明確其 type,type 和 Virtue call 有時可唯一綁定,但通常不能唯一綁定。此時使用靜態(tài)分析技術(shù),可明確 Virtue call type 的可能范圍,實現(xiàn)封閉。

          受靜態(tài)分析本身的特性和能力所限,靜態(tài)分析得到的可達代碼集合(藍色)略大于實際執(zhí)行代碼集合(綠色)。靜態(tài)分析精度越高、冗余越少、image 越小。

          基于配置的動態(tài)特性支持

          靜態(tài)分析無法分析出 Java 的許多動態(tài)特性運行時的行為,如反射、動態(tài)代理、JNI、序列化(阿里巴巴貢獻,從 21.0 開始支持)、動態(tài)類加載(阿里巴巴貢獻,patch 已經(jīng)通過評審)等。此時需提前獲取所需信息,方可封閉此類動態(tài)特性的觸達范圍——即需基于配置進行動態(tài)特性支持。


          以反射為例。SVM 提供了 native-image-agent,可記錄 APP 運行時所有的反射。編譯時只需解析配置文件,即可注冊反射目標,擴大編譯范圍;同時獲取反射信息后可放入 ReflectionData 緩存中,將反射調(diào)用替換為直接調(diào)用。運行時如遇反射可查找 ReflectionData,獲取目標值,通過 Method.invoke 直接調(diào)用目標函數(shù)。

          下圖為通過靜態(tài)編譯和傳統(tǒng) Java 兩種方式,分別用反射調(diào)用空函數(shù) 30 次性能對比測試結(jié)果:

          由于峰值過高,該圖進行了對數(shù)修正。傳統(tǒng) Java 編譯空函數(shù)耗時(深藍色)為 3000ns,峰值由于反射開銷為 4000ns,靜態(tài)編譯后(深藍色)穩(wěn)定在 150ns 內(nèi)。

          SVM 的靜態(tài)編譯實現(xiàn)的編譯優(yōu)化包括標準優(yōu)化如:Method inlining, constant folding and arithmetic optimization, loop optimization, partial escape analysis 等。

          此外還有因為靜態(tài)分析而引入的新的編譯優(yōu)化,例如未被標為 final 的 field 通過靜態(tài)分析發(fā)現(xiàn)只讀不寫,即可當作常量處理,做常量折疊等優(yōu)化;又如,靜態(tài)分析出某虛函數(shù) type 唯一綁定,即可優(yōu)化為直接調(diào)用,進而實現(xiàn) inline;再如,消除部分編譯時已知變量類型狀態(tài)的類型檢查和空指針檢查。

          主要運行時組件

          靜態(tài)編譯由于所有的類均已被編譯因此只有一個類加載器,實際只執(zhí)行類查找功能。

          傳統(tǒng) Java 一邊檢查異常一邊運行,如遇異常直接處理即可。SVM 考慮到在不同平臺兼容性,異常處理采用非信號處理機制:檢測無錯方可正常運行。該檢測對性能影響小。

          此外,靜態(tài)編譯的 GC 為 Oracle 開源版本中的單線程 stop-and-copy 順序 GC,性能一般。

          性能對比 - 實驗室數(shù)據(jù)

          下圖為 Graal VM 官方的實驗數(shù)據(jù):

          如上圖所示,在只執(zhí)行 Hello world 程序時,Native Image 性能次于 C,與 Go 相當,遠快于傳統(tǒng) JDK;內(nèi)存使用次于 C,只有 Go 的一半,遠低于傳統(tǒng) JDK,具有高性能低內(nèi)存占用的優(yōu)點。圖中紅色數(shù)據(jù)為受測語言數(shù)據(jù)除以 Native Image 數(shù)據(jù)所得比值。

          性能對比 - 實際場景數(shù)據(jù)

          Javac 為 Java 編寫的編譯器:可以在 Java 程序中來調(diào)用 API 編譯,也可用 stand alone 工具編譯。通過 API 調(diào)用,實際上已完成 VM 啟動,因此兩者對比可觀察冷啟動帶來的性能差異。

          通過 API 調(diào)用 Javac 耗時 250ms,使用 Native Image 后耗時達到 35ms,實現(xiàn)了 1 個數(shù)量級的飛躍。

          Javac 中使用的反射、Serverless 較少,其他項目靜態(tài)分析性能提升效果更加顯著。下圖為基于 spring boot 的應(yīng)用 greeting-service 部署在阿里云函數(shù)計算平臺上的數(shù)據(jù)。greeting-service 收到請求會返回“ hallo”,功能簡單但需要 spring boot 全流程支持。

          如圖所示,Native Image 靜態(tài)編譯(橙色)相比傳統(tǒng) Java(藍色):內(nèi)存占用從 128MB 降至 21MB;實際第一次調(diào)用耗時從 454 ms 降至 4.27 ms,提升了兩個數(shù)量級;阿里云服務(wù)計費從 500ms 降至 100ms,事半功倍。

          靜態(tài)編譯局限性


          靜態(tài)編譯的局限性如上表所示:

          • 為實現(xiàn)封閉性,反射、動態(tài)代理、JNI、序列化、動態(tài)類加載均需要通過配置支持;

          • 不支持 InvokeDynamic(開發(fā)人員使用)、Method Handles(開發(fā)人員使用)、Security Manager、多 classloader、Finalizers、過時 Thread 函數(shù)(如 Thread.stop())等;

          • Java 程序被靜態(tài)編譯后不再保留 bytecode,因此存在監(jiān)控、調(diào)試方面的問題:不支持 JVMTI、JMX、agent,只能使用 GDB 調(diào)試,無法通過 Eclipse IDE、IntelliJ IDEA 等調(diào)試。

          GraalVM 生態(tài)發(fā)展

          GraalVM 靜態(tài)編譯目前生態(tài)如下:

          • 阿里云:通過阿里云函數(shù)計算平臺進行支持部署 serverless Native Image 應(yīng)用,通過 Apache RocketMQ 為 C++ 客戶端提供使用靜態(tài)編譯的 Java 共享庫;

          • Spring 社區(qū):發(fā)布了針對于靜態(tài)編譯 Spring-Native beta 版本,完全支持 Spring 的運算;

          • MICRONAUT:實現(xiàn)了支持 Native Image 的去反射微服務(wù)框架;

          • Facebook & Twitter:均在生產(chǎn)環(huán)境下使用 Graal 編譯器代替 C2 編譯器。

          總之,在 Serverless 場景下 Java 的冷啟動問題與應(yīng)用對快速響應(yīng)、實時擴展的需求形成突出矛盾。阿里巴巴一方面在現(xiàn)有技術(shù)上不斷改進,最終形成突破:EagerAppCDS 提升最多 45% 的啟動速度;另一方面積極參與開源社區(qū)探索創(chuàng)新型的前沿技術(shù),打磨成熟用于實踐:GraalVM 靜態(tài)編譯技術(shù)最多提升百倍啟動速度。但 GraalVM 存在兼容性和改造成本的問題,適合新項目。

          來源 | QCon全球軟件開發(fā)大會

          嘉賓 | 林子熠? ? ?

          整理 | 李慧文


          THE?END
          熱門推薦:

          PS:如果覺得我的分享不錯,歡迎大家隨手點贊、轉(zhuǎn)發(fā)、在看。
          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91麻豆精品成一区二区 | 91视频久久久久久久久久久 | 嘛豆三级片电影 | 操死我网站 | 成人性在线 |